okta / okta-sdk-dotnet

A .NET SDK for interacting with the Okta management API, enabling server-side code to manage Okta users, groups, applications, and more.
Other
160 stars 100 forks source link

Okta.Sdk.IIdentityProvider object does not have access to SAML2 Metadata and AssertionConsumerService object #570

Closed pmatpadi closed 2 years ago

pmatpadi commented 2 years ago

Describe the bug?

Referring to https://developer.okta.com/docs/reference/api/idps/#add-saml-2-0-identity-provider, on successful SAML2 IDP creation, the response contains _links->metadata and _links->acs, which we need to return to the client. I do not see a documented way to retrieve these from Okta.Sdk.IIdentityProvider object using okta dotnet sdk. How can I get access to _links->metadata and _links->acs from response of _oktaInstance.IdentityProviders.CreateIdentityProviderAsync()?

What is expected to happen?

The SDK response for IDP provisioning should contain SAML2 IDP metadata and ACS information.

What is the actual behavior?

The SDK response for IDP provisioning does not contain SAML2 IDP metadata and ACS information or any of the misc. information returned by Okta API.

Reproduction Steps?

    public async Task<IIdentityProvider> CreateOktaIDPAsync(IIdentityProvider idp, CancellationToken cancellationToken)
    {
        return await _oktaInstance.IdentityProviders.CreateIdentityProviderAsync(idp, cancellationToken);
    }

Additional Information?

No response

.NET Version

6.0

SDK Version

5.6.0

OS version

NA

laura-rodriguez commented 2 years ago

Hi @pmatpadi,

Thank you for your inquiry.

All the models in the SDK extend from Resource which is basically a wrapper for the raw data and allows you to get any property from the model, even those that are not exposed. To access the _links property or any children you can try the following:

var identityProvider = await client.IdentityProviders.CreateOktaIDPAsync(idp);
var links = identityProvider.GetProperty<Resource>("_links");
var acs = links.GetProperty<Resource>("acs");
var acsType = acs.GetProperty<string>("type");

For other examples, see here

I agree this should be documented, so I'm gonna file an internal ticket to improve docs. Let me know if this helps.

laura-rodriguez commented 2 years ago

Internal Ref: OKTA-518033

pmatpadi commented 2 years ago

Thank you! This helped resolve the issue I raised. However, I am having trouble with unit testing my code retrieving the idp response fields using the indexer pattern with "Moq" Version="4.18.1".

var newIdp = new Mock<IIdentityProvider>();

var acsUrl = $"https://{fakeOktaDomain}/sso/saml2/{oktaIdpId}"; ;
var acsResource = new Resource();
acsResource.SetProperty("href", acsUrl);

var linksResource = new Resource();
linksResource.SetProperty("metadata", metadataResource);
linksResource.SetProperty("acs", acsResource);

newIdp.SetupGet(x => x["_links"]).Returns(linksResource);

Following code in the assertion returns null value

var links = newIdp.GetProperty<Resource>("_links");

I also tried below, but Moq does not allow this-

newIdp.SetupGet(x => x.GetProperty<Resource>("_links")).Returns(linksResource);

throws

System.ArgumentException : Expression is not a property access: x => x.GetProperty<Resource>("_links")
    Stack Trace:
       at Moq.ExpressionExtensions.ToPropertyInfo(LambdaExpression expression) in C:\projects\moq4\src\Moq\ExpressionExtensions.cs:line 395
   at Moq.Mock.SetupGet(Mock mock, LambdaExpression expression, Condition condition) in C:\projects\moq4\src\Moq\Mock.cs:line 512
   at Moq.Mock`1.SetupGet[TProperty](Expression`1 expression) in C:\projects\moq4\src\Moq\Mock`1.cs:line 473

Any helpful tips on how to write a successful unit test?

bryanapellanes-okta commented 2 years ago

@pmatpadi I have some familiarity with Moq and I believe you should get the results you're looking for if you use "Setup" instead of "SetupGet" like this:

newIdp.Setup(x => x.GetProperty<Resource>("_links")).Returns(linksResource);

This should tell Moq that you're mocking a method call instead of a property accessor.

pmatpadi commented 2 years ago

Thanks so much @bryanapellanes-okta . That solved the unit test issue 😄