Class GrouperOktaProvisioningTargetNativeSync

java.lang.Object
edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningTargetNativeSync
edu.internet2.middleware.grouper.app.okta.GrouperOktaProvisioningTargetNativeSync

public class GrouperOktaProvisioningTargetNativeSync extends GrouperProvisioningTargetNativeSync
Okta-specific GrouperProvisioningTargetNativeSync: builds native target reporting beans for sync-back to the generic grouper_prov_group / grouper_prov_user tables.

Both groups and users are captured from the raw Okta JSON (JSON Pointer paths, like SCIM/Adobe), hooked at the API-commands seam (GrouperOktaApiCommands.retrieveOktaGroups / retrieveOktaGroup and retrieveOktaUsers / retrieveOktaUser / retrieveOktaUserById) where the full JSON node is in scope. This avoids losing any Okta field that the GrouperOktaGroup / GrouperOktaUser typed beans do not model; operators can capture any JSON field via nativeAttributesGroups / nativeAttributesEntities with a name and optional JSON-Pointer path.

Okta objects are NESTED: a group's identity id lives at the top level (/id) but its descriptive fields live under profile (/profile/name, /profile/description); likewise a user's id is at /id, its lifecycle status at /status, and its descriptive fields under profile (/profile/login, /profile/email, /profile/firstName, ...). The default capture pointers therefore reach into /profile/*, matching exactly what GrouperOktaGroup.fromJson(com.fasterxml.jackson.databind.JsonNode) / GrouperOktaUser.fromJson(com.fasterxml.jackson.databind.JsonNode) read.

Group/user OBJECTS capture only on the READ path (from the raw JSON above); there is no write-side capture of group/user objects. MEMBERSHIPS, by contrast, now capture on WRITE: the DAO's insert/deleteMembership call captureMembershipInsertFromCurrentProvisioner(java.lang.String, java.lang.String) / captureMembershipDeleteFromCurrentProvisioner(java.lang.String, java.lang.String) on success, which record into the native membership mirror (recordTargetNativeMembershipInsert/Delete) -- the same membership write-track design as Adobe/SCIM/Dropbox, so a membership add/remove converges on the write pass. Memberships are also still derived group-centrically from the per-group member-id fetch on the read path (captureMembershipsForGroup(java.lang.String, java.lang.Iterable<java.lang.String>)); Okta has no retrieve-all-memberships call, so that per-group member fetch is the only read-path place both ids are co-located -- the same situation as Adobe/Google.

  • Constructor Details

    • GrouperOktaProvisioningTargetNativeSync

      public GrouperOktaProvisioningTargetNativeSync()
  • Method Details

    • getDefaultNativeAttributeConfigsEntities

      protected List<GrouperProvisioningNativeAttributeConfig> getDefaultNativeAttributeConfigsEntities()
      Description copied from class: GrouperProvisioningTargetNativeSync
      Per-protocol sensible-default attribute list for entities (users) when the operator hasn't configured nativeAttributesEntities. Override in protocol subclasses to return a curated list (e.g. SCIM core schema fields). Default is empty — for LDAP this means "no extra capture beyond what the regular target query returned," which is the historical behavior.
      Overrides:
      getDefaultNativeAttributeConfigsEntities in class GrouperProvisioningTargetNativeSync
    • getDefaultNativeAttributeConfigsGroups

      protected List<GrouperProvisioningNativeAttributeConfig> getDefaultNativeAttributeConfigsGroups()
      Description copied from class: GrouperProvisioningTargetNativeSync
      Per-protocol sensible-default attribute list for groups. See GrouperProvisioningTargetNativeSync.getDefaultNativeAttributeConfigsEntities().
      Overrides:
      getDefaultNativeAttributeConfigsGroups in class GrouperProvisioningTargetNativeSync
    • buildNativeGroupFromJson

      public GrouperProvisioningTargetNativeGroup buildNativeGroupFromJson(com.fasterxml.jackson.databind.JsonNode groupNode)
      Build a native group bean from the raw Okta group JSON. targetId is read from the top-level /id (the same field GrouperOktaGroup.fromJson(com.fasterxml.jackson.databind.JsonNode) uses for the id); the attributes map is populated for each entry in GrouperProvisioningTargetNativeSync.effectiveNativeAttributeConfigsGroups() (operator-configured or default) by JSON Pointer, which for the defaults reaches into /profile/*. Returns null when the JSON is missing or has no id.
    • buildNativeUserFromJson

      public GrouperProvisioningTargetNativeUser buildNativeUserFromJson(com.fasterxml.jackson.databind.JsonNode userNode)
      Build a native user bean from the raw Okta user JSON. targetId is read from the top-level /id (the same field GrouperOktaUser.fromJson(com.fasterxml.jackson.databind.JsonNode) uses for the id); the attributes map is populated for each entry in GrouperProvisioningTargetNativeSync.effectiveNativeAttributeConfigsEntities() (operator-configured or default) by JSON Pointer, which for the defaults reaches into /profile/*. Returns null when the JSON is missing or has no id.
    • captureGroupJson

      public void captureGroupJson(com.fasterxml.jackson.databind.JsonNode groupNode)
      Build + record an Okta group from its raw JSON. No-op when sync-back is off or id-less.
    • captureUserJson

      public void captureUserJson(com.fasterxml.jackson.databind.JsonNode userNode)
      Build + record an Okta user from its raw JSON. No-op when sync-back is off or id-less.
    • captureMembershipsForGroup

      public void captureMembershipsForGroup(String targetGroupId, Iterable<String> targetUserIds)
      Build native membership beans for all member user ids in the supplied group, and record them. No-op if reporting is off or the input is empty. Okta membership is group-centric: the member ids come from the per-group member fetch during DAO translation, not from the group object's JSON (the object does not carry its members), so this path is untouched by the move to raw-JSON object capture.
    • captureGroupJsonFromCurrentProvisioner

      public static void captureGroupJsonFromCurrentProvisioner(com.fasterxml.jackson.databind.JsonNode groupNode)
      Capture an Okta group (from its raw JSON) against the current provisioner's sync. No-op if there's no current provisioner or the active provisioner isn't an Okta one. Called from the commands seam (GrouperOktaApiCommands.retrieveOktaGroups / retrieveOktaGroup) for every group read.
    • captureUserJsonFromCurrentProvisioner

      public static void captureUserJsonFromCurrentProvisioner(com.fasterxml.jackson.databind.JsonNode userNode)
      Capture an Okta user (from its raw JSON) against the current provisioner's sync. No-op if there's no current provisioner or the active provisioner isn't an Okta one. Called from the commands seam (GrouperOktaApiCommands.retrieveOktaUsers / retrieveOktaUser / retrieveOktaUserById).
    • captureMembershipsForGroupForCurrentProvisioner

      public static void captureMembershipsForGroupForCurrentProvisioner(String targetGroupId, Iterable<String> targetUserIds)
      Record memberships for a given target group id against the current provisioner's sync. Okta membership is group-centric and derived during DAO translation, so this stays a typed dispatch (the ids are plain strings, not JSON) -- only the group/user object capture moved to raw JSON.
    • captureMembershipInsertFromCurrentProvisioner

      public static void captureMembershipInsertFromCurrentProvisioner(String targetGroupId, String targetUserId)
      Write-track a successful Okta membership add (createOktaMembership) against the current provisioner: record (targetGroupId, targetUserId) in the native membership map. No-op out of cycle or for a non-Okta provisioner.
    • captureMembershipDeleteFromCurrentProvisioner

      public static void captureMembershipDeleteFromCurrentProvisioner(String targetGroupId, String targetUserId)
      Write-track a successful Okta membership remove (deleteOktaMembership) against the current provisioner: drop (targetGroupId, targetUserId) from the native membership map so the end-of-run flush deletes its grouper_prov_mship row.