public async Task GetCurrentConfiguration()
        {
            var rawResponse         = @"{
    ""action"": ""audit"",
    ""excludeZones"": [""nzo1q7jEOsoCnoKcj0g4""],
    ""created"": ""2020-08-05 22:18:30"",
    ""lastUpdated"": ""2020-09-08 20:53:20"",
    ""_links"": {
        ""self"": {
            ""href"": ""https://${yourOktaDomain}/api/v1/threats/configuration"",
            ""hints"": {
                ""allow"": [
                    ""GET"",
                    ""POST""
                ]
            }
        }
    }
}";
            var mockRequestExecutor = new MockedStringRequestExecutor(rawResponse);
            var client = new TestableOktaClient(mockRequestExecutor);
            var threatInsightClient = client.ThreatInsights;

            var response = await threatInsightClient.GetCurrentConfigurationAsync();

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/threats/configuration");
            response.Action.Should().Be("audit");
            response.ExcludeZones.Should().OnlyContain(z => z.Equals("nzo1q7jEOsoCnoKcj0g4"));
        }
        public async Task ListSocialAuthTokens()
        {
            var rawResponse = @"[{
                                  ""id"": ""dsasdfe"",
                                  ""token"": ""JBTWGV22G4ZGKV3N"",
                                  ""tokenType"" : ""urn:ietf:params:oauth:token-type:access_token"",
                                  ""tokenAuthScheme"": ""Bearer"",
                                  ""expiresAt"" : ""2014-08-06T16:56:31.000Z"",
                                  ""scopes""     : [ ""openid"", ""foo"" ]
                                }]";

            var mockRequestExecutor = new MockedStringRequestExecutor(rawResponse);
            var client = new TestableOktaClient(mockRequestExecutor);

            var tokens = await client.IdentityProviders.ListSocialAuthTokens("0oa62b57p7c8PaGpU0h7", "00ub0oNGTSWTBKOLGLNR").ToListAsync();

            mockRequestExecutor.ReceivedHref.Should().StartWith("/api/v1/idps/0oa62b57p7c8PaGpU0h7/users/00ub0oNGTSWTBKOLGLNR/credentials/tokens");

            tokens.Should().HaveCount(1);
            tokens.FirstOrDefault().Id.Should().Be("dsasdfe");
            tokens.FirstOrDefault().Token.Should().Be("JBTWGV22G4ZGKV3N");
            tokens.FirstOrDefault().TokenType.Should().Be("urn:ietf:params:oauth:token-type:access_token");
            tokens.FirstOrDefault().TokenAuthScheme.Should().Be("Bearer");
            tokens.FirstOrDefault().Scopes.Should().ContainInOrder("openid", "foo");
        }
        public async Task CreateCustomIdp()
        {
            var rawResponse = @"{
                                  ""id"": ""foo"",
                                  ""issuerMode"": ""ORG_URL"",
                                  ""name"": ""dotnet-sdk:AddGeneric2021-10-20 3:37:36 PM"",
                                  ""status"": ""INACTIVE"",
                                  ""created"": ""2021-10-20T15:37:37.000Z"",
                                  ""lastUpdated"": ""2021-10-20T15:37:37.000Z"",
                                }";

            var mockRequestExecutor = new MockedStringRequestExecutor(rawResponse);
            var client = new TestableOktaClient(mockRequestExecutor);

            var idp = new IdentityProvider()
            {
                Type = "CUSTOM TYPE IDP",
                Name = $"dotnet-sdk:Custom Idp",
            };

            var createdIdp = await client.IdentityProviders.CreateIdentityProviderAsync(idp);

            var expectedBody = $"{{\"type\":\"CUSTOM TYPE IDP\",\"name\":\"dotnet-sdk:Custom Idp\"}}";

            mockRequestExecutor.ReceivedHref.Should().StartWith("/api/v1/idps");
            mockRequestExecutor.ReceivedBody.Should().Be(expectedBody);
        }
Пример #4
0
        public async Task ListUserGrants()
        {
            var rawResponse         = @"[
                                    {
                                        ""id"": ""oag3ih1zrm1cBFOiq0h6"",
                                        ""status"": ""ACTIVE"",
                                        ""created"": ""2017-10-30T22:06:53.000Z"",
                                        ""lastUpdated"": ""2017-10-30T22:06:53.000Z"",
                                        ""issuer"": ""https://${yourOktaDomain}/oauth2/ausain6z9zIedDCxB0h7"",
                                        ""clientId"": ""0oabskvc6442nkvQO0h7"",
                                        ""userId"": ""00u5t60iloOHN9pBi0h7"",
                                        ""scopeId"": ""scpCmCCV1DpxVkCaye2X"",
                                        ""_links"": {
                                            ""app"": {
                                                ""href"": ""https://${yourOktaDomain}/api/v1/apps/0oabskvc6442nkvQO0h7"",
                                                ""title"": ""My App""
                                            },
                                            ""scope"": {
                                                ""href"": ""https://${yourOktaDomain}/api/v1/authorizationServers/ausain6z9zIedDCxB0h7/scopes/scpCmCCV1DpxVkCaye2X"",
                                                ""title"": ""My phone""
                                            },
                                            ""client"": {
                                                ""href"": ""https://${yourOktaDomain}/oauth2/v1/clients/0oabskvc6442nkvQO0h7"",
                                                ""title"": ""My App""
                                            },
                                            ""self"": {
                                                ""href"": ""https://${yourOktaDomain}/api/v1/users/00u5t60iloOHN9pBi0h7/grants/oag3ih1zrm1cBFOiq0h6"",
                                                ""hints"": {
                                                    ""allow"": [
                                                        ""GET"",
                                                        ""DELETE""
                                                    ]
                                                }
                                            },
                                            ""user"": {
                                                ""href"": ""https://${yourOktaDomain}/api/v1/users/00u5t60iloOHN9pBi0h7"",
                                                ""title"": ""SAML Jackson""
                                            },
                                            ""authorizationServer"": {
                                                ""href"": ""https://${yourOktaDomain}/api/v1/authorizationServers/ausain6z9zIedDCxB0h7"",
                                                ""title"": ""Example Authorization Server""
                                            }
                                        }
                                    }
                                ]";
            var mockRequestExecutor = new MockedStringRequestExecutor(rawResponse);
            var client = new TestableOktaClient(mockRequestExecutor);
            var grants = await client.Users.ListUserGrants("foo").ToListAsync();

            grants.Should().NotBeNull();
            grants.Count.Should().Be(1);
            grants[0].Id.Should().Be("oag3ih1zrm1cBFOiq0h6");
            grants[0].Status.Should().Be(OAuth2ScopeConsentGrantStatus.Active);
            grants[0].Issuer.Should().Be("https://${yourOktaDomain}/oauth2/ausain6z9zIedDCxB0h7");
            grants[0].ClientId.Should().Be("0oabskvc6442nkvQO0h7");
            grants[0].UserId.Should().Be("00u5t60iloOHN9pBi0h7");
            grants[0].ScopeId.Should().Be("scpCmCCV1DpxVkCaye2X");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/users/foo/grants?limit=20");
        }
Пример #5
0
        public async Task ListUserClients()
        {
            var rawResponse         = @"[
                                    {
                                        ""client_id"": ""0oabskvc6442nkvQO0h7"",
                                        ""client_name"": ""My App"",
                                        ""client_uri"": null,
                                        ""logo_uri"": null,
                                        ""_links"": {
                                            ""grants"": {
                                                ""href"": ""https://${yourOktaDomain}/api/v1/users/00u5t60iloOHN9pBi0h7/clients/0oabskvc6442nkvQO0h7/grants""
                                            },
                                            ""tokens"": {
                                                ""href"": ""https://${yourOktaDomain}/api/v1/users/00u5t60iloOHN9pBi0h7/clients/0oabskvc6442nkvQO0h7/tokens""
                                            }
                                        }
                                    }
                                ]";
            var mockRequestExecutor = new MockedStringRequestExecutor(rawResponse);
            var client      = new TestableOktaClient(mockRequestExecutor);
            var userClients = await client.Users.ListUserClients("foo").ToListAsync();

            userClients.Should().NotBeNull();
            userClients.Count.Should().Be(1);
            userClients[0].ClientId.Should().Be("0oabskvc6442nkvQO0h7");
            userClients[0].ClientName.Should().Be("My App");
            userClients[0].ClientUri.Should().BeNullOrEmpty();
            userClients[0].LogoUri.Should().BeNullOrEmpty();

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/users/foo/clients");
        }
        public async Task UpdateProfileMapping()
        {
            var expectedBody        = @"{""properties"":{""fullName"":{""expression"":""user.firstName + user.lastName"",""pushStatus"":""PUSH""},""nickName"":{""expression"":""user.nickName"",""pushStatus"":""PUSH""}}}";
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);
            var profileMappingsClient = client.ProfileMappings;

            var data = new Dictionary <string, object>
            {
                ["properties"] = new Dictionary <string, object>
                {
                    ["fullName"] = new Dictionary <string, object>
                    {
                        ["expression"] = "user.firstName + user.lastName",
                        ["pushStatus"] = "PUSH",
                    },
                    ["nickName"] = new Dictionary <string, object>
                    {
                        ["expression"] = "user.nickName",
                        ["pushStatus"] = "PUSH",
                    },
                },
            };

            var factory = new ResourceFactory(null, null);
            var mapping = factory.CreateNew <ProfileMapping>(data);

            await profileMappingsClient.UpdateProfileMappingAsync(mapping, "mappingId");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/mappings/mappingId");
            mockRequestExecutor.ReceivedBody.Should().Be(expectedBody);
        }
Пример #7
0
        public async Task ThrowApiExceptionFor4xx()
        {
            var rawErrorResponse    = @"
{
    ""errorCode"": ""E0000011"",
    ""errorSummary"": ""Invalid token provided"",
    ""errorLink"": ""E0000011"",
    ""errorId"": ""oaelUIU6UZ_RxuqVbi3pxR1ag"",
    ""errorCauses"": []
}";
            var mockRequestExecutor = new MockedStringRequestExecutor(rawErrorResponse, 400);
            var client = new TestableOktaClient(mockRequestExecutor);

            try
            {
                await client.Users.GetUserAsync("12345");
            }
            catch (OktaApiException apiException)
            {
                apiException.Message.Should().Be("Invalid token provided (400, E0000011)");
                apiException.ErrorCode.Should().Be("E0000011");
                apiException.ErrorSummary.Should().Be("Invalid token provided");
                apiException.ErrorLink.Should().Be("E0000011");
                apiException.ErrorId.Should().Be("oaelUIU6UZ_RxuqVbi3pxR1ag");
                apiException.Error.Should().NotBeNull();
            }
        }
Пример #8
0
        public async Task ResetFactors()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);
            await client.Users.ResetFactorsAsync("foo");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/users/foo/lifecycle/reset_factors");
        }
Пример #9
0
        public async Task AddAllAppsAsTargetToRole()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);
            await client.Users.AddAllAppsAsTargetToRoleAsync("foo", "bar");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/users/foo/roles/bar/targets/catalog/apps");
        }
Пример #10
0
        public async Task RevokeTokenForUserAndClient()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);
            await client.Users.RevokeTokenForUserAndClientAsync("foo", "bar", "baz");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/users/foo/clients/bar/tokens/baz");
        }
Пример #11
0
        public async Task ReactivateUser() // Difficult to create a user with "PROVISIONED" status; core api requires user in a "PROVISIONED" status in order to reactivate.
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);
            await client.Users.ReactivateUserAsync("foo");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/users/foo/lifecycle/reactivate?sendEmail=false");
        }
Пример #12
0
        public async Task ClearUserOAuthSessions()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);
            await client.Users.ClearUserSessionsAsync("foo", true);

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/users/foo/sessions?oauthTokens=true");
        }
Пример #13
0
        public async Task GetUserGrant()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);
            await client.Users.GetUserGrantAsync("foo", "bar");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/users/foo/grants/bar?");
        }
Пример #14
0
        public void ReturnEmptyListWhenFeaturesIsNullInTheResponse()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(GetBookmarkApplicationStubResponse());
            var client = new TestableOktaClient(mockRequestExecutor);

            var app = client.Applications.GetApplicationAsync <IBookmarkApplication>("foo").Result;

            app.Features.Any().Should().BeFalse();
        }
Пример #15
0
        public async Task RemoveApplicationTargetFromApplicationAdministratorRoleGivenToGroup()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty, 204);
            var client = new TestableOktaClient(mockRequestExecutor);

            await client.Groups.RemoveApplicationTargetFromApplicationAdministratorRoleGivenToGroupAsync("foo", "bar", "baz");

            mockRequestExecutor.ReceivedHref.Should().StartWith("/api/v1/groups/foo/roles/bar/targets/catalog/apps/baz");
        }
Пример #16
0
        public void NotReturnNullWhenFeaturesHasNoData()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(GetBookmarkApplicationStubResponse(features: "[]"));
            var client = new TestableOktaClient(mockRequestExecutor);

            var app = client.Applications.GetApplicationAsync <IBookmarkApplication>("foo").Result;

            app.Features.Any().Should().BeFalse();
        }
        public async Task UnlinkUser()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty, 204);
            var client = new TestableOktaClient(mockRequestExecutor);

            await client.IdentityProviders.UnlinkUserFromIdentityProviderAsync("0oa4lb6lbtmH355Hx0h7", "00u5cl9lo7nMjHjPr0h7");

            mockRequestExecutor.ReceivedHref.Should().StartWith("/api/v1/idps/0oa4lb6lbtmH355Hx0h7/users/00u5cl9lo7nMjHjPr0h7");
        }
Пример #18
0
        public async Task BuildRevokeTokensRequest()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);

            await client.Applications.RevokeOAuth2TokensForApplicationAsync("foo");

            mockRequestExecutor.ReceivedHref.Should().StartWith("/api/v1/apps/foo/tokens");
        }
Пример #19
0
        public async Task BuildPublishBinaryPemCertRequest()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);

            await client.Applications.PublishBinaryPemCertAsync(Encoding.UTF8.GetBytes("certificateByteDataFromFile"), "testAppId", "testCertificateSigningRequestId");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/apps/testAppId/credentials/csrs/testCertificateSigningRequestId/lifecycle/publish");
        }
Пример #20
0
        public async Task AddApplicationTargetToAppAdminRoleForUser()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty, 204);
            var client = new TestableOktaClient(mockRequestExecutor);

            await client.Users.AddApplicationTargetToAppAdminRoleForUserAsync("foo", "bar", "baz", "bax");

            mockRequestExecutor.ReceivedHref.Should().StartWith("/api/v1/users/foo/roles/bar/targets/catalog/apps/baz/bax");
        }
Пример #21
0
        public async Task BuildPublishCerCertRequest()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);

            await client.Applications.PublishCerCertAsync("fakeBase64EncodedCertificate", "testAppId", "testCertificateSigningRequestId");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/apps/testAppId/credentials/csrs/testCertificateSigningRequestId/lifecycle/publish");
        }
Пример #22
0
        public async Task VerifyDomain()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);

            var domainsClient = client.Domains;
            await domainsClient.VerifyDomainAsync("domainid");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/domains/domainid/verify");
        }
Пример #23
0
        public async Task GetResourceAsInterface()
        {
            var json = @"{
  ""id"": ""foobar123""
}";
            var mockRequestExecutor = new MockedStringRequestExecutor(json);
            var client = new TestableOktaClient(mockRequestExecutor);

            var app = await client.Applications.GetApplicationAsync <IApplication>("apps/foobar123");

            app.Id.Should().Be("foobar123");
        }
Пример #24
0
        public async Task ListGrantsForUserAndClient()
        {
            var rawResponse         = @"[
                                  {
                                    ""id"": ""oar579Mcp7OUsNTlo0g3"",
                                    ""status"": ""ACTIVE"",
                                    ""created"": ""2018-03-09T03:18:06.000Z"",
                                    ""lastUpdated"": ""2018-03-09T03:18:06.000Z"",
                                    ""expiresAt"": ""2018-03-16T03:18:06.000Z"",
                                    ""issuer"": ""https://${yourOktaDomain}/oauth2/ausain6z9zIedDCxB0h7"",
                                    ""clientId"": ""0oabskvc6442nkvQO0h7"",
                                    ""userId"": ""00u5t60iloOHN9pBi0h7"",
                                    ""scopes"": [
                                      ""offline_access"",
                                      ""car:drive""
                                    ],
                                    ""_links"": {
                                      ""app"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/apps/0oabskvc6442nkvQO0h7"",
                                        ""title"": ""Native""
                                      },
                                      ""self"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/users/00u5t60iloOHN9pBi0h7/clients/0oabskvc6442nkvQO0h7/tokens/oar579Mcp7OUsNTlo0g3""
                                      },
                                      ""revoke"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/users/00u5t60iloOHN9pBi0h7/clients/0oabskvc6442nkvQO0h7/tokens/oar579Mcp7OUsNTlo0g3"",
                                        ""hints"": {
                                          ""allow"": [
                                            ""DELETE""
                                          ]
                                        }
                                      },
                                      ""client"": {
                                        ""href"": ""https://${yourOktaDomain}/oauth2/v1/clients/0oabskvc6442nkvQO0h7"",
                                        ""title"": ""Example Client App""
                                      },
                                      ""user"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/users/00upcgi9dyWEOeCwM0g3"",
                                        ""title"": ""Saml Jackson""
                                      },
                                      ""authorizationServer"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/authorizationServers/ausain6z9zIedDCxB0h7"",
                                        ""title"": ""Example Authorization Server""
                                      }
                                    }
                                  }
                                ]";
            var mockRequestExecutor = new MockedStringRequestExecutor(rawResponse);
            var client = new TestableOktaClient(mockRequestExecutor);
            await client.Users.ListGrantsForUserAndClient("foo", "bar").ToListAsync();

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/users/foo/clients/bar/grants?limit=20");
        }
Пример #25
0
        public void AddCustomFeaturesToAnEmptyFeaturesList()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(GetBookmarkApplicationStubResponse(features: "[]"));
            var client = new TestableOktaClient(mockRequestExecutor);

            var app = client.Applications.GetApplicationAsync <IBookmarkApplication>("foo").Result;

            app.Features.Any().Should().BeFalse();

            app.Features.Add("custom_feature");
            app.Features.Any().Should().BeTrue();
        }
Пример #26
0
        public async Task DeactivateAuthenticatorAsync()
        {
            var rawResponse = @"{
                                ""type"": ""security_key"",
                                ""id"": ""aut1nd8PQhGcQtSxB0g4"",
                                ""key"": ""webauthn"",
                                ""status"": ""INACTIVE"",
                                ""name"": ""Security Key or Biometric"",
                                ""created"": ""2020-07-26T21:16:37.000Z"",
                                ""lastUpdated"": ""2020-07-26T21:59:33.000Z"",
                                ""_links"": {
                                    ""self"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/authenticators/aut1nd8PQhGcQtSxB0g4"",
                                        ""hints"": {
                                            ""allow"": [
                                                ""GET"",
                                                ""PUT""
                                            ]
                                        }
                                    },
                                    ""methods"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/authenticators/aut1nd8PQhGcQtSxB0g4/methods"",
                                        ""hints"": {
                                            ""allow"": [
                                                ""GET""
                                            ]
                                        }
                                    },
                                    ""deactivate"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/authenticators/aut1nd8PQhGcQtSxB0g4/lifecycle/deactivate"",
                                        ""hints"": {
                                            ""allow"": [
                                                ""POST""
                                            ]
                                        }
                                    }
                                }
                            }";

            var mockRequestExecutor = new MockedStringRequestExecutor(rawResponse);
            var client = new TestableOktaClient(mockRequestExecutor);

            var authenticator = await client.Authenticators.DeactivateAuthenticatorAsync("aut1nd8PQhGcQtSxB0g4");

            authenticator.Id.Should().Be("aut1nd8PQhGcQtSxB0g4");
            authenticator.Status.Should().Be(AuthenticatorStatus.Inactive);
            authenticator.Key.Should().Be("webauthn");
            authenticator.Name.Should().Be("Security Key or Biometric");

            mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/authenticators/aut1nd8PQhGcQtSxB0g4/lifecycle/deactivate");
        }
Пример #27
0
        public async Task HandleEmptyPayloadDuringGet()
        {
            // If the API returns a null or empty payload, it shouldn't cause an error.

            var requestExecutor = new MockedStringRequestExecutor(string.Empty, statusCode: 200);
            var dataStore       = new DefaultDataStore(requestExecutor, new DefaultSerializer(), new ResourceFactory(null, null), NullLogger.Instance);
            var request         = new HttpRequest {
                Uri = "https://foo.dev"
            };

            var response = await dataStore.GetAsync <TestResource>(request, new RequestContext(), CancellationToken.None);

            response.StatusCode.Should().Be(200);
            response.Payload.Should().NotBeNull();
            response.Payload.Foo.Should().BeNullOrEmpty();
        }
        public async Task EnrollHotpFactor()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);

            var factorsClient     = client.UserFactors;
            var hotpFactorOptions = new AddCustomHotpFactorOptions
            {
                FactorProfileId     = "fpr20l2mDyaUGWGCa0g4",
                ProfileSharedSecret = "484f97be3213b117e3a20438e291540a",
            };
            await factorsClient.AddFactorAsync("UserId", hotpFactorOptions);

            mockRequestExecutor.ReceivedHref.Should().Match("/api/v1/users/UserId/factors*activate=true*");
            mockRequestExecutor.ReceivedBody.Should().Be("{\"factorType\":\"token:hotp\",\"provider\":\"CUSTOM\",\"factorProfileId\":\"fpr20l2mDyaUGWGCa0g4\",\"profile\":{\"sharedSecret\":\"484f97be3213b117e3a20438e291540a\"}}");
        }
        public async Task EnrollEmailFactor()
        {
            var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty);
            var client = new TestableOktaClient(mockRequestExecutor);

            var factorsClient      = client.UserFactors;
            var emailFactorOptions = new AddEmailFactorOptions
            {
                Email = "*****@*****.**",
                TokenLifetimeSeconds = 999,
            };
            await factorsClient.AddFactorAsync("UserId", emailFactorOptions);

            mockRequestExecutor.ReceivedHref.Should().Match("/api/v1/users/UserId/factors*tokenLifetimeSeconds=999*");
            mockRequestExecutor.ReceivedBody.Should().Be("{\"factorType\":\"email\",\"provider\":\"OKTA\",\"profile\":{\"email\":\"[email protected]\"}}");
        }
        public async Task GetIdentityProviderApplicationUser()
        {
            var rawResponse = @"{
                                ""id"": ""00u5t60iloOHN9pBi0h7"",
                                ""externalId"": ""externalId"",
                                ""created"": ""2017-12-19T17:30:16.000Z"",
                                ""lastUpdated"": ""2017-12-19T17:30:16.000Z"",
                                ""profile"": {
                                    ""profileUrl"": null,
                                    ""firstName"": null,
                                    ""lastName"": null,
                                    ""honorificSuffix"": null,
                                    ""displayName"": null,
                                    ""honorificPrefix"": null,
                                    ""middleName"": null,
                                    ""email"": null
                                },
                                ""_links"": {
                                    ""idp"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/idps/0oa62bfdiumsUndnZ0h7""
                                    },
                                    ""self"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/idps/0oa62bfdiumsUndnZ0h7/users/00u5t60iloOHN9pBi0h7"",
                                        ""hints"": {
                                            ""allow"": [
                                                ""GET"",
                                                ""DELETE""
                                            ]
                                        }
                                    },
                                    ""user"": {
                                        ""href"": ""https://${yourOktaDomain}/api/v1/users/00u5t60iloOHN9pBi0h7""
                                    }
                                }
                            }";

            var mockRequestExecutor = new MockedStringRequestExecutor(rawResponse);
            var client = new TestableOktaClient(mockRequestExecutor);

            var user = await client.IdentityProviders.GetIdentityProviderApplicationUserAsync("0oa62bfdiumsUndnZ0h7", "00u5t60iloOHN9pBi0h7");

            mockRequestExecutor.ReceivedHref.Should().StartWith("/api/v1/idps/0oa62bfdiumsUndnZ0h7/users/00u5t60iloOHN9pBi0h7");

            user.Should().NotBeNull();
            user.Id.Should().Be("00u5t60iloOHN9pBi0h7");
            user.ExternalId.Should().Be("externalId");
        }