okta/okta-sdk-golang

Get application API call from okta server fails through go-sdk

c0d3r-arnab opened this issue · 6 comments

Describe the bug?

The function GetApplication of okta package fails to fetch details of a specific application. It makes a GET request to {{url}}/api/v1/apps/{{appId}} and then fails to unmarshal object into Go value of type okta.App.

What is expected to happen?

The API call should return a response related to the specific application.

What is the actual behavior?

The following error occurs:

Error: json: cannot unmarshal object into Go value of type okta.App

Reproduction Steps?

Make a GET call for a specific application through the SDK.

Additional Information?

A similar error was fixed in v2 for the function ListApplications. Here is the link to the issue: #87

Golang Version

go version go1.17.2 darwin/amd64

SDK Version

2.9.2

OS version

Darwin turbotindias-MacBook-Pro.local 20.5.0 Darwin Kernel Version 20.5.0: Sat May 8 05:10:33 PDT 2021; root:xnu-7195.121.3~9/RELEASE_X86_64 x86_64

Thank you for the report @c0d3r-arnab . The information provided will help us a lot, but I need a couple more bits of information related to the application.

  • Can you provide me with the type of application you are trying to access.
  • Can you do a cURL call to the endpoint and paste the response here? (feel free to remove any private information)
  • A stack trace may also be of use if possible.

Hello @bretterer! Thank you for the quick response.

  • Can you provide me with the type of application you are trying to access.
    I believe I have API services. Please find the response for all the applications I have in the attached zip file. I hope that will provide some clarity.

  • Can you do a cURL call to the endpoint and paste the response here?
    You will find the curl response for the GET API request in the attached zip file.

  • A stack trace may also be of use if possible
    I am really sorry but I cannot provide a stack trace as I do not have one with me.

Please do let me know if you need anything else from me.

Responses.zip

monde commented

@c0d3r-arnab thanks for the Responses.zip, that is really helpful. I just want to make sure the json in list_apps.json is the actual data returned for the curl command in the get_curl.txt log. If you notice in your log the curl command is indeed calling the get application API endpoint https://${url}/api/v1/apps/${id} but the json in the list_apps.json is an array of all the applications on your org which would correspond to the get applications endpoint https://${url}/api/v1/apps. Also, the name of the json data file implies it is from a call to the get (list) applications endpoint.

Can you let me know what version of okta-sdk-golang you are using? Perhaps there is a bug in a specific release and I'll need to look into that tag specifically. When I run our integration test for the GetApplication endpoint it passes for me:

https://github.com/okta/okta-sdk-golang/blob/master/tests/integration/application_test.go#L35-L61

go test -test.v -run ^Test_can_get_application_by_id$ ./tests/integration/...
2021/12/15 10:33:02 [INFO] sweeping test users, groups and rules
=== RUN   Test_can_get_application_by_id
--- PASS: Test_can_get_application_by_id (1.11s)
PASS
2021/12/15 10:33:04 [INFO] sweeping test users, groups and rules
ok      github.com/okta/okta-sdk-golang/v2/tests/integration    2.591s

Hello @monde!! Thank you for the clarification. The list response I gave was for the API call: {{url}}/api/v1/apps. I could not get the GET API call running via GO SDK. So I provided the list of all the apps that I have and a curl response for the GET call.

However, after looking at your test case code, I made some changes to my code and I have been able to make it work. Here is my current code that is working:

app, _, err := client.Application.GetApplication(ctx, appId, okta.NewApplication(), &query.Params{})

My previous code was like this:

var application okta.App
app, _, err := client.Application.GetApplication(ctx, appId, application, &query.Params{})

In the definition of GetApplication, I see the appInstance is of type okta.App as in the below image:
Screenshot 2021-12-16 at 11 33 52 AM

That is the reason why I instantiated the parameter in my previous code as okta.App. In the new code, which is working, okta.NewApplication() is of type Application.

So out of curiosity, since the type of the parameter appInstance in the GetApplication function and the parameter I am passing, i.e, okta.NewApplication(), don't seem to match, can you please clarify how is this working? Please note that I don't get the mentioned error anymore with the new code.

monde commented

Hi @c0d3r-arnab

okta.App is an interface https://github.com/okta/okta-sdk-golang/blob/master/okta/application.go#L29-L31

And okta.BasicAuthApplication implements that interface https://github.com/okta/okta-sdk-golang/blob/master/okta/basicAuthApplication.go#L25-L53

okta.NewBasicAuthApplication() returns a pointer of okta.BasicAuthApplication, therefore, you can pass it as a parameter of type okta.App.

Go By Example has a nice example of golang interfaces and types implementing interfaces and how to use them as a pointer reference:

https://gobyexample.com/interfaces

One last thing to get your first attempt to compile it would have been something like:

// assuming you are getting a basic auth application
var application okta.BasicAuthApplication
// notice the '&' of &application ... that is a pointer reference to the memory where var application is established
app, _, err := client.Application.GetApplication(ctx, appId, &application, &query.Params{})

Let me know if you need any more help, I'll close this issue now.

@monde Thank you for the explanation. I do not have any further queries.