Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for custom user profile attributes #749

Merged
merged 6 commits into from
Aug 23, 2022

Conversation

arvindkrishnakumar-okta
Copy link
Contributor

@arvindkrishnakumar-okta arvindkrishnakumar-okta commented Aug 11, 2022

Issue(s)

Description

Category

  • Bugfix
  • Enhancement
  • New Feature
  • Library Upgrade
  • Configuration Change
  • Versioning Change
  • Unit or Integration Test(s)
  • Documentation

Signoff

  • I have submitted a CLA for this PR
  • Each commit message explains what the commit does
  • I have updated documentation to explain what my PR does
  • My code is covered by tests if required
  • I did not edit any automatically generated files

@arvindkrishnakumar-okta arvindkrishnakumar-okta changed the base branch from master to oasv3 August 11, 2022 12:20
@@ -620,6 +627,7 @@ class UsersIT extends ITSupport {

assertThat(updatedUser.lastUpdated, greaterThan(originalLastUpdated))
assertThat(updatedUser.getProfile().getProperties().get("nickName"), equalTo("Batman"))
//assertThat(updatedUser.getProfile().getAdditionalProperties().get("key1"), equalTo("val1"))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented this because the ITs will be run in several Org cells as part of PDV runs. For this IT to run successfully, this custom profile property must first be added to the User schema via Console UI. Since this is not possible, we are disabling this test to prevent IT failures under such circumstances.

// the respective property must first be associated to the User schema.
// You can use the Profile Editor in your Org's administrator UI or the Schemas API
// to manage schema extensions.
//userProfile.getAdditionalProperties().put("key1", "val1")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below comment for reasoning behind why this line is commented out.

Copy link
Collaborator

@laura-rodriguez laura-rodriguez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM, however, I suggest autogenerating the additionalProperties serialization instead of creating the serializer manually. SImilarly to what the codegen does with okhttp-gson:

public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
    @SuppressWarnings("unchecked")
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
       if (!UserProfile.class.isAssignableFrom(type.getRawType())) {
         return null; // this class only serializes 'UserProfile' and its subtypes
       }
       final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
       final TypeAdapter<UserProfile> thisAdapter
                        = gson.getDelegateAdapter(this, TypeToken.get(UserProfile.class));

       return (TypeAdapter<T>) new TypeAdapter<UserProfile>() {
           @Override
           public void write(JsonWriter out, UserProfile value) throws IOException {
             JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
             obj.remove("additionalProperties");
             // serialize additonal properties
             if (value.getAdditionalProperties() != null) {
               for (Map.Entry<String, Object> entry : value.getAdditionalProperties().entrySet()) {
                 if (entry.getValue() instanceof String)
                   obj.addProperty(entry.getKey(), (String) entry.getValue());
                 else if (entry.getValue() instanceof Number)
                   obj.addProperty(entry.getKey(), (Number) entry.getValue());
                 else if (entry.getValue() instanceof Boolean)
                   obj.addProperty(entry.getKey(), (Boolean) entry.getValue());
                 else if (entry.getValue() instanceof Character)
                   obj.addProperty(entry.getKey(), (Character) entry.getValue());
                 else {
                   obj.add(entry.getKey(), gson.toJsonTree(entry.getValue()).getAsJsonObject());
                 }
               }
             }
             elementAdapter.write(out, obj);
           }

           @Override
           public UserProfile read(JsonReader in) throws IOException {
             JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject();
             validateJsonObject(jsonObj);
             // store additional fields in the deserialized instance
             UserProfile instance = thisAdapter.fromJsonTree(jsonObj);
             for (Map.Entry<String, JsonElement> entry : jsonObj.entrySet()) {
               if (!openapiFields.contains(entry.getKey())) {
                 if (entry.getValue().isJsonPrimitive()) { // primitive type
                   if (entry.getValue().getAsJsonPrimitive().isString())
                     instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsString());
                   else if (entry.getValue().getAsJsonPrimitive().isNumber())
                     instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsNumber());
                   else if (entry.getValue().getAsJsonPrimitive().isBoolean())
                     instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsBoolean());
                   else
                     throw new IllegalArgumentException(String.format("The field `%s` has unknown primitive type. Value: %s", entry.getKey(), entry.getValue().toString()));
                 } else { // non-primitive type
                   instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), HashMap.class));
                 }
               }
             }
             return instance;
           }

       }.nullSafe();
    }
  }

@arvindkrishnakumar-okta arvindkrishnakumar-okta merged commit 361e42a into oasv3 Aug 23, 2022
@arvindkrishnakumar-okta arvindkrishnakumar-okta deleted the ak_add_custom_user_profile_support branch August 23, 2022 20:45
arvindkrishnakumar-okta added a commit that referenced this pull request Oct 26, 2022
…776)

* Regenerate and rewrite for OASv3 using `openapi-generator.tech` (#737)


* minor refactor

* minor refactor

* fix Travis build failure

* added circle ci config

* added jdk18 to circle ci config

* minor refactor

* minor refactor

* minor refactor

* minor refactor

* removed unwanted file

* updated readme and migrating guides and other refactoring

* [maven-release-plugin] prepare release okta-sdk-root-10.0.0-beta

* [maven-release-plugin] prepare for next development iteration

* Release pr 10.0.0 beta (#747)

* [maven-release-plugin] prepare release okta-sdk-root-10.0.0-beta

* [maven-release-plugin] prepare for next development iteration

* Update README.md

* Add support for custom user profile attributes (#749)

* add support for custom user profile attributes

* added license header on new files

* fix build failure

* refactored

* refactored

* refactored

* [OASv3] - OAuth for Okta (#753)

* wip - oauth for okta

* fix unit test failure

* fix unit test failure

* OKTA-526761: Add Caching support (#768)

* add caching

* OKTA-537443: Add Groups ITs (#772)

added GroupsIT

* OKTA-537444: Add Policy ITs (#773)

* added PoliciesIT (signon)

* Regen sdk with latest oasv3 spec (#774)

* added PoliciesIT (signon)

* updated PolicyIT

* regen and refactor sdk with latest oasv3 spec

* minor update

* fix build

* cve fix and prep for oasv3 GA release (#777)

* cve fix and prep for oasv3 GA release

* removed unwanted yaml file

* revert jakarta annotation back to 1.3.5

* updated migration guide

* updated circle ci config
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants