Call other API endpoints using Okta Management API Java

Hi,

I’m looking for using the okta-sdk-api to create/update/delete entities that are not represented by a method in the library.

As said in the Readme of the GitHub page :

Not every API endpoint is represented by a method in this library. You can call any Okta management API endpoint using this generic syntax:

// Create an IdP, see: https://developer.okta.com/docs/api/resources/idps#add-identity-provider
ExtensibleResource resource = client.instantiate(ExtensibleResource.class);
ExtensibleResource protocolNode = client.instantiate(ExtensibleResource.class);
protocolNode.put("type", "OAUTH");
resource.put("protocol", protocolNode);
ExtensibleResource result = client.http()
    .setBody(resource)  
    .post("/api/v1/idps", ExtensibleResource.class); 

But I’m not getting how to build the ExtensibleResource to fit in the body method. For example for a TrustedOrigins API object I’ve tried something like that but I’m getting a ERROR::HTTP 400, Okta E0000003 (The request body was not well-formed.) error. With :

        JSONObject object = toCreate.getJSONObject(i);
        String name = object.getString("name");
        String origin = object.getString("origin");
        JSONArray scopes = object.getJSONArray("scopes");

        ExtensibleResource extensibleResource = okta.instantiate(ExtensibleResource.class);
        extensibleResource.put("protocol", protocolNode);
        extensibleResource.put("name", name);
        extensibleResource.put("origin", origin);
        extensibleResource.put("scopes", scopes);

        TrustedOrigin trustedOrigin = okta.http()
                .setBody(extensibleResource)
                .post("/api/v1/trustedOrigins", TrustedOrigin.class);

Object is a JSONObject from a parsed JSON string of a GET request from Okta.

Could you help me see more clearly how to do this please ?

Thank you

Not specifically answering how to work with ExtensibleResource but addressing TrustedOrigin

https://developer.okta.com/okta-sdk-java/development/apidocs/com/okta/sdk/client/Client.html#createOrigin-com.okta.sdk.resource.trusted.origin.TrustedOrigin-

That’s not helping me, because creating a TrustedOrigiun object is really complexe because it’s an interface and there are a ton of function to implement.

I’m not sure how to properly do it, just an example would be enough I guess.

(I’m having the same problem when integrating the /users API because I need to user setProvider(AuthenticationProvider provider) but I can’t build the AuthenticationProvider Object for the same reason)

what is it for in a call to trustedOrigin?

val extensibleResource: ExtensibleResource = client.instantiate(ExtensibleResource::class.java)
extensibleResource["name"] = "Test"
extensibleResource["origin"] = "https://test.com"
extensibleResource["scopes"] = listOf(
    client.instantiate(ExtensibleResource::class.java).also {
        it["type"] = "CORS"
    },
    client.instantiate(ExtensibleResource::class.java).also {
        it["type"] = "REDIRECT"
    }
)

val trustedOrigin: TrustedOrigin = client.http()
    .setBody(extensibleResource)
    .post("/api/v1/trustedOrigins", TrustedOrigin::class.java)

That looks like Javascript to me right ?

Also I’ve used this :

`extensibleResource.put("protocol", protocolNode);`

Because it is what’s written inside the documenation of the sdk : https://github.com/okta/okta-sdk-java#call-other-api-endpoints

A restranscription of what you’ve done should be :

JSONObject object = toCreate.getJSONObject(i);
            String name = object.getString("name");
            String origin = object.getString("origin");
            JSONArray scopes = object.getJSONArray("scopes");

            List<String> scopeList = new ArrayList<>();
            for (int j = 0; j < scopes.length(); j++) {
                scopeList.add(scopes.get(j).toString());
            }


            ExtensibleResource extensibleResource = okta.instantiate(ExtensibleResource.class);
            extensibleResource.put("name", name);
            extensibleResource.put("origin", origin);
            extensibleResource.put("scopes", scopeList);

            TrustedOrigin trustedOrigin = okta.http()
                    .setBody(extensibleResource)
                    .post("/api/v1/trustedOrigins", TrustedOrigin.class);

But I already tried this without success

for API call you should consult Okta API documentation, which tells what the request to /trustedOrigins should look like.

your transcription is wrong, as my example shows that scopes is an array of ExtensibleResource objects

Are you saying something like that ?

            JSONArray scopes = object.getJSONArray("scopes");
            ArrayList<ExtensibleResource> scopeList = new ArrayList<>();

            for (int j = 0; j < scopes.length(); j++) {
                ExtensibleResource scope = okta.instantiate(ExtensibleResource.class);
                scope.put("type", scopes.get(j));
                scopeList.add(scope);
            }

            ExtensibleResource extensibleResource = okta.instantiate(ExtensibleResource.class);
            extensibleResource.put("name", name);
            extensibleResource.put("origin", origin);
            extensibleResource.put("scopes", scopeList);

            TrustedOrigin trustedOrigin = okta.http()
                    .setBody(extensibleResource)
                    .post("/api/v1/trustedOrigins", TrustedOrigin.class);

I’m getting the same error here. Building a JSON payload is way easier that this, or I’m not getting something obvious ?

what is the type of scopes.get(j) in your code fragment? is it a String? Try to hard code, instead of extracting from JSONArray and see if it’s the issue

Ok you were right, hardcoding allowed me to find the issue. The use of a JSONObject caused the problem.

So now I’m converting my JSONObject to a Map to build my payload and it works now !

            JSONArray scopes = object.getJSONArray("scopes");

            ArrayList<ExtensibleResource> scopeList = new ArrayList<>();

            for (int j = 0; j < scopes.length(); j++) {
                HashMap<String, Object> scopeMap = new Gson().fromJson(scopes.getJSONObject(j).toString(), HashMap.class);

                scopeMap.forEach((key, value) -> {
                    ExtensibleResource scope = okta.instantiate(ExtensibleResource.class);
                    scope.put(key,value);
                    scopeList.add(scope);
                });
            }

            ExtensibleResource extensibleResource = okta.instantiate(ExtensibleResource.class);
            extensibleResource.put("name", name);
            extensibleResource.put("origin", origin);
            extensibleResource.put("scopes", scopeList);

            TrustedOrigin trustedOrigin = okta.http()
                    .setBody(extensibleResource)
                    .post("/api/v1/trustedOrigins", TrustedOrigin.class);

Thank you !

1 Like