From 14057734b9ac68256797ebe595f1baee96724d39 Mon Sep 17 00:00:00 2001 From: mchyzer Date: Thu, 17 Nov 2022 09:45:26 -0500 Subject: [PATCH] 2.6.18 --- Dockerfile | 2 +- .../ProvisioningSyncIntegration.class | Bin 28851 -> 0 bytes .../ProvisioningSyncIntegration.java | 846 ----------- .../ldap/ldaptive/LdaptiveSessionImpl$1.class | Bin 4766 -> 0 bytes .../ldaptive/LdaptiveSessionImpl$10.class | Bin 1829 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl$2.class | Bin 4916 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl$3.class | Bin 2947 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl$4.class | Bin 5061 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl$5.class | Bin 3018 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl$6.class | Bin 4276 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl$7.class | Bin 6922 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl$8.class | Bin 5089 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl$9.class | Bin 5723 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl.class | Bin 36442 -> 0 bytes .../ldap/ldaptive/LdaptiveSessionImpl.java | 1292 ----------------- .../libWs/jersey-container-servlet-2.36.jar | Bin 32381 -> 0 bytes 16 files changed, 1 insertion(+), 2139 deletions(-) delete mode 100644 container_files/api/edu/internet2/middleware/grouper/app/tableSync/ProvisioningSyncIntegration.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/app/tableSync/ProvisioningSyncIntegration.java delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$1.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$10.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$2.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$3.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$4.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$5.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$6.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$7.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$8.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$9.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl.class delete mode 100644 container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl.java delete mode 100644 container_files/grouperWebapp/WEB-INF/libWs/jersey-container-servlet-2.36.jar diff --git a/Dockerfile b/Dockerfile index 531da553..a6f62ddf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ LABEL author="tier-packaging@internet2.edu " \ ARG GROUPER_CONTAINER_VERSION -ENV GROUPER_VERSION=2.6.17 \ +ENV GROUPER_VERSION=2.6.18 \ GROUPER_CONTAINER_VERSION=$GROUPER_CONTAINER_VERSION \ JAVA_HOME=/usr/lib/jvm/java-1.8.0-amazon-corretto \ PATH=$PATH:$JAVA_HOME/bin \ diff --git a/container_files/api/edu/internet2/middleware/grouper/app/tableSync/ProvisioningSyncIntegration.class b/container_files/api/edu/internet2/middleware/grouper/app/tableSync/ProvisioningSyncIntegration.class deleted file mode 100644 index ad9971a55c6cfd10d99a286448e11e66505d070a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28851 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 P1_(xFwH2mKsVn~ initialGcGrouperSyncGroups, Map groupUuidToProvisioningObjectAttributes) { - - if (gcGrouperSync == null || StringUtils.isBlank(gcGrouperSync.getProvisionerName())) { - throw new RuntimeException("provisioner name is required"); - } - - if (!GrouperProvisioningSettings.getTargets(true).containsKey(gcGrouperSync.getProvisionerName())) { - throw new RuntimeException("Target '" + gcGrouperSync.getProvisionerName() - + "' is not configured. Go to Miscellaneous -> Provisioning to configure a new target."); - } - - Map groupUuidToSyncGroup = new HashMap(); - - initialGcGrouperSyncGroups = GrouperUtil.nonNull(initialGcGrouperSyncGroups); - - for (GcGrouperSyncGroup gcGrouperSyncGroup : initialGcGrouperSyncGroups) { - groupUuidToSyncGroup.put(gcGrouperSyncGroup.getGroupId(), gcGrouperSyncGroup); - } - - int removeSyncRowsAfterSecondsOutOfTarget = GrouperLoaderConfig.retrieveConfig().propertyValueInt( - "grouper.provisioning.removeSyncRowsAfterSecondsOutOfTarget", 60*60*24*7); - - provisioningSyncGroupResult.setGcGrouperSync(gcGrouperSync); - - // start group ids to insert with all group ids minus those which have sync group objects already - Set groupIdsToInsert = new HashSet(groupUuidToProvisioningObjectAttributes.keySet()); - provisioningSyncGroupResult.setGroupIdsToInsert(groupIdsToInsert); - groupIdsToInsert.removeAll(groupUuidToSyncGroup.keySet()); - - Set groupIdsToUpdate = new HashSet(); - provisioningSyncGroupResult.setGroupIdsToUpdate(groupIdsToUpdate); - - List gcGrouperSyncRowsToDeleteFromDatabase = new ArrayList(); - - Set groupIdsWithChangedIdIndexes = new HashSet(); - provisioningSyncGroupResult.setGroupIdsWithChangedIdIndexes(groupIdsWithChangedIdIndexes); - - Set groupIdsWithChangedNames = new HashSet(); - provisioningSyncGroupResult.setGroupIdsWithChangedNames(groupIdsWithChangedNames); - - - // lets remove ones that dont need to be there - if (GrouperUtil.length(groupUuidToSyncGroup) > 0) { - - // make an array list so we can remove from the map without exception - List gcGrouperSyncGroups = new ArrayList(groupUuidToSyncGroup.values()); - - for (GcGrouperSyncGroup gcGrouperSyncGroup : gcGrouperSyncGroups) { - - GrouperProvisioningObjectAttributes grouperProvisioningObjectAttributes = groupUuidToProvisioningObjectAttributes.get(gcGrouperSyncGroup.getGroupId()); - - String newGroupName = grouperProvisioningObjectAttributes == null ? null : grouperProvisioningObjectAttributes.getName(); - Long newGroupIdIndex = grouperProvisioningObjectAttributes == null ? null : grouperProvisioningObjectAttributes.getIdIndex(); - String newMetadataJson = grouperProvisioningObjectAttributes == null ? null : grouperProvisioningObjectAttributes.getProvisioningMetadataJson(); - boolean groupIsProvisionable = grouperProvisioningObjectAttributes != null; - - gcGrouperSyncGroup.setMetadataJson(newMetadataJson); - - processSyncGroup(groupUuidToSyncGroup, - removeSyncRowsAfterSecondsOutOfTarget, groupIdsToInsert, groupIdsToUpdate, - gcGrouperSyncRowsToDeleteFromDatabase, groupIdsWithChangedIdIndexes, - groupIdsWithChangedNames, gcGrouperSyncGroup, grouperProvisioningObjectAttributes, - newGroupName, newGroupIdIndex, newMetadataJson, groupIsProvisionable); - } - - gcGrouperSync.getGcGrouperSyncGroupDao().groupDelete(gcGrouperSyncRowsToDeleteFromDatabase, true, true); - } - - if (GrouperUtil.length(groupIdsToInsert) > 0) { - - Map mapGroupIdToSyncGroupInsert = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveOrCreateByGroupIds(groupIdsToInsert); - - for (String groupIdToInsert : mapGroupIdToSyncGroupInsert.keySet()) { - - GcGrouperSyncGroup gcGrouperSyncGroup = mapGroupIdToSyncGroupInsert.get(groupIdToInsert); - initialGcGrouperSyncGroups.add(gcGrouperSyncGroup); - GrouperProvisioningObjectAttributes grouperProvisioningObjectAttributes = groupUuidToProvisioningObjectAttributes.get(groupIdToInsert); - - if (grouperProvisioningObjectAttributes == null) { - continue; - } - String groupName = grouperProvisioningObjectAttributes.getName(); - Long groupIdIndex = grouperProvisioningObjectAttributes.getIdIndex(); - String groupMetadataJson = grouperProvisioningObjectAttributes.getProvisioningMetadataJson(); - - processSyncGroupInsert(gcGrouperSync, groupUuidToSyncGroup, groupIdToInsert, - gcGrouperSyncGroup, groupName, groupIdIndex, groupMetadataJson); - } - - } - - Set groupIdsToDelete = new HashSet(groupUuidToSyncGroup.keySet()); - - provisioningSyncGroupResult.setGroupIdsToDelete(groupIdsToDelete); - - groupIdsToDelete.removeAll(groupUuidToProvisioningObjectAttributes.keySet()); - - processSyncGroupDelete(groupUuidToSyncGroup, groupIdsToDelete); - - } - - public static void processSyncGroupDelete( - Map groupUuidToSyncGroup, - Set groupIdsToDelete) { - if (GrouperUtil.length(groupIdsToDelete) > 0) { - - Iterator groupIdToDeleteIterator = groupIdsToDelete.iterator(); - - while (groupIdToDeleteIterator.hasNext()) { - - String groupIdToDelete = groupIdToDeleteIterator.next(); - - GcGrouperSyncGroup gcGrouperSyncGroup = groupUuidToSyncGroup.get(groupIdToDelete); - - if (gcGrouperSyncGroup == null) { - throw new RuntimeException("why is gcGrouperSyncGroup null???"); - } - - if (gcGrouperSyncGroup.isProvisionable() || gcGrouperSyncGroup.getProvisionableEnd() == null) { - gcGrouperSyncGroup.setProvisionable(false); - gcGrouperSyncGroup.setProvisionableEnd(new Timestamp(System.currentTimeMillis())); - } - - // if we arent in target, dont worry about it - if (!gcGrouperSyncGroup.isInTarget() ) { - groupIdToDeleteIterator.remove(); - groupUuidToSyncGroup.remove(gcGrouperSyncGroup.getGroupId()); - } - - } - - } - } - - public static void processSyncMemberDelete( - Map memberUuidToSyncMember, - Set memberIdsToDelete) { - - if (GrouperUtil.length(memberIdsToDelete) > 0) { - - Iterator memberIdToDeleteIterator = memberIdsToDelete.iterator(); - - while (memberIdToDeleteIterator.hasNext()) { - - String memberIdToDelete = memberIdToDeleteIterator.next(); - - GcGrouperSyncMember gcGrouperSyncMember = memberUuidToSyncMember.get(memberIdToDelete); - - if (gcGrouperSyncMember == null) { - throw new RuntimeException("why is gcGrouperSyncMember null???"); - } - - if (gcGrouperSyncMember.isProvisionable() || gcGrouperSyncMember.getProvisionableEnd() == null) { - gcGrouperSyncMember.setProvisionable(false); - gcGrouperSyncMember.setProvisionableEnd(new Timestamp(System.currentTimeMillis())); - } - - // if we arent in target, dont worry about it - if (!gcGrouperSyncMember.isInTarget() ) { - memberIdToDeleteIterator.remove(); - memberUuidToSyncMember.remove(gcGrouperSyncMember.getMemberId()); - } - - } - - } - } - - public static void processSyncGroupInsert(GcGrouperSync gcGrouperSync, - Map groupUuidToSyncGroup, String groupIdToInsert, - GcGrouperSyncGroup gcGrouperSyncGroup, String groupName, - Long groupIdIndex, String metadataJson) { - if (gcGrouperSyncGroup == null) { - gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().groupCreateByGroupId(groupIdToInsert); - } - gcGrouperSyncGroup.setGroupName(groupName); - gcGrouperSyncGroup.setGroupIdIndex(groupIdIndex); - gcGrouperSyncGroup.setMetadataJson(metadataJson); - gcGrouperSyncGroup.setProvisionable(true); - gcGrouperSyncGroup.setProvisionableStart(new Timestamp(System.currentTimeMillis())); - groupUuidToSyncGroup.put(groupIdToInsert, gcGrouperSyncGroup); - } - - public static void processSyncGroup( - Map groupUuidToSyncGroup, - int removeSyncRowsAfterSecondsOutOfTarget, Set groupIdsToInsert, - Set groupIdsToUpdate, - List gcGrouperSyncRowsToDeleteFromDatabase, - Set groupIdsWithChangedIdIndexes, Set groupIdsWithChangedNames, - GcGrouperSyncGroup gcGrouperSyncGroup, - GrouperProvisioningObjectAttributes grouperProvisioningObjectAttributes, String newGroupName, - Long newGroupIdIndex, String newMetadataJson, boolean groupIsProvisionable) { - -// { -// // is in grouper? -// Boolean inGrouper = null; -// if (inGrouper == null && provisioningGroupWrapper != null && provisioningGroupWrapper.isDelete()) { -// inGrouper = false; -// } -// if (inGrouper == null && provisioningGroupWrapper.getGrouperProvisioningGroup() != null) { -// inGrouper = true; -// } -// if (inGrouper == null && groupIsProvisionable) { -// inGrouper = true; -// } -// if (inGrouper == null) { -// inGrouper = false; -// } -// if (gcGrouperSyncGroup.getInGrouper() != inGrouper) { -// if (gcGrouperSyncGroup.getInGrouperInsertOrExistsDb() == null) { -// gcGrouperSyncGroup.setInTargetInsertOrExists(false); -// } -// gcGrouperSyncGroup.setInGrouper(inGrouper); -// if (inGrouper) { -// gcGrouperSyncGroup.setInGrouperStart(new Timestamp(System.currentTimeMillis())); -// } else { -// gcGrouperSyncGroup.setInGrouperEnd(new Timestamp(System.currentTimeMillis())); -// } -// } -// } -// - // keep it - if (groupIsProvisionable || gcGrouperSyncGroup.isProvisionable() || gcGrouperSyncGroup.isInTarget()) { - - // see if needs to update - { - if (!StringUtils.equals(newGroupName, gcGrouperSyncGroup.getGroupName())) { - groupIdsWithChangedNames.add(gcGrouperSyncGroup.getGroupId()); - if (newGroupName != null) { - gcGrouperSyncGroup.setGroupName(newGroupName); - } - } - } - - { - if (!GrouperUtil.equals(newGroupIdIndex, gcGrouperSyncGroup.getGroupIdIndex())) { - groupIdsWithChangedIdIndexes.add(gcGrouperSyncGroup.getGroupId()); - if (newGroupIdIndex != null) { - gcGrouperSyncGroup.setGroupIdIndex(newGroupIdIndex); - } - } - } - - // see if not provisionable - if (!gcGrouperSyncGroup.isProvisionable() && groupIsProvisionable) { - gcGrouperSyncGroup.setProvisionableStart(new Timestamp(System.currentTimeMillis())); - gcGrouperSyncGroup.setProvisionableEnd(null); - gcGrouperSyncGroup.setProvisionable(true); - } - if (gcGrouperSyncGroup.isProvisionable() && !groupIsProvisionable) { - gcGrouperSyncGroup.setProvisionableEnd(new Timestamp(System.currentTimeMillis())); - gcGrouperSyncGroup.setProvisionable(false); - } - - // see if not provisionable - if (!gcGrouperSyncGroup.isInTarget() && groupIsProvisionable) { - groupIdsToInsert.add(gcGrouperSyncGroup.getGroupId()); - } - - if (gcGrouperSyncGroup.dbVersionDifferent()) { - groupIdsToUpdate.add(gcGrouperSyncGroup.getGroupId()); - } - - } - - groupUuidToSyncGroup.remove(gcGrouperSyncGroup.getGroupId()); - - //if we arent provisionable, and the group has not been in the target for a week, then we done with that one - if (!gcGrouperSyncGroup.isInTarget() && !gcGrouperSyncGroup.isProvisionable() && gcGrouperSyncGroup.getInTargetEnd() != null) { - long targetEndMillis = gcGrouperSyncGroup.getInTargetEnd() == null ? 0 : gcGrouperSyncGroup.getInTargetEnd().getTime(); - targetEndMillis = Math.max(targetEndMillis, gcGrouperSyncGroup.getProvisionableEnd() == null ? 0 : gcGrouperSyncGroup.getProvisionableEnd().getTime()); - targetEndMillis = Math.max(targetEndMillis, gcGrouperSyncGroup.getLastUpdated() == null ? 0 : gcGrouperSyncGroup.getLastUpdated().getTime()); - if (targetEndMillis != 0 &&( (System.currentTimeMillis() - targetEndMillis) / 1000 > removeSyncRowsAfterSecondsOutOfTarget)) { - gcGrouperSyncRowsToDeleteFromDatabase.add(gcGrouperSyncGroup); - } - } - } - - public static void fullSyncMembers(GrouperProvisioner grouperProvisioner, ProvisioningSyncResult provisioningSyncResult, GcGrouperSync gcGrouperSync, - List initialGcGrouperSyncMembers, - Map memberUuidToProvisioningObjectAttributes) { - - if (gcGrouperSync == null || StringUtils.isBlank(gcGrouperSync.getProvisionerName())) { - throw new RuntimeException("provisioner name is required"); - } - - if (!GrouperProvisioningSettings.getTargets(true).containsKey(gcGrouperSync.getProvisionerName())) { - throw new RuntimeException("Target '" + gcGrouperSync.getProvisionerName() - + "' is not configured. Go to Miscellaneous -> Provisioning to configure a new target."); - } - - Map memberUuidToSyncMember = new HashMap(); - - initialGcGrouperSyncMembers = GrouperUtil.nonNull(initialGcGrouperSyncMembers); - - for (GcGrouperSyncMember gcGrouperSyncMember : initialGcGrouperSyncMembers) { - memberUuidToSyncMember.put(gcGrouperSyncMember.getMemberId(), gcGrouperSyncMember); - } - - int removeSyncRowsAfterSecondsOutOfTarget = GrouperLoaderConfig.retrieveConfig().propertyValueInt( - "grouper.provisioning.removeSyncRowsAfterSecondsOutOfTarget", 60*60*24*7); - - provisioningSyncResult.setGcGrouperSync(gcGrouperSync); - - // start member ids to insert with all member ids minus those which have sync member objects already - Set memberIdsToInsert = new HashSet(memberUuidToProvisioningObjectAttributes.keySet()); - provisioningSyncResult.setMemberIdsToInsert(memberIdsToInsert); - memberIdsToInsert.removeAll(memberUuidToSyncMember.keySet()); - - Set memberIdsToUpdate = new HashSet(); - provisioningSyncResult.setMemberIdsToUpdate(memberIdsToUpdate); - - Set gcGrouperSyncRowsToDeleteFromDatabase = new HashSet(); - - Set memberIdsWithChangedSubjectIds = new HashSet(); - provisioningSyncResult.setMemberIdsWithChangedSubjectIds(memberIdsWithChangedSubjectIds); - - // lets remove ones that dont need to be there - if (GrouperUtil.length(memberUuidToSyncMember) > 0) { - - // make an array list so we can remove from the map without exception - List gcGrouperSyncMembers = new ArrayList(memberUuidToSyncMember.values()); - - for (GcGrouperSyncMember gcGrouperSyncMember: gcGrouperSyncMembers) { - - GrouperProvisioningObjectAttributes grouperProvisioningObjectAttributes = memberUuidToProvisioningObjectAttributes.get(gcGrouperSyncMember.getMemberId()); - - String newMetadataJson = grouperProvisioningObjectAttributes == null ? null : grouperProvisioningObjectAttributes.getProvisioningMetadataJson(); - gcGrouperSyncMember.setMetadataJson(newMetadataJson); - - //if we arent provisionable, and the member has not been in the target for a week, then we done with that one - if (!gcGrouperSyncMember.isInTarget() && !gcGrouperSyncMember.isProvisionable() && gcGrouperSyncMember.getInTargetEnd() != null) { - long targetEndMillis = gcGrouperSyncMember.getInTargetEnd() == null ? 0 : gcGrouperSyncMember.getInTargetEnd().getTime(); - targetEndMillis = Math.max(targetEndMillis, gcGrouperSyncMember.getProvisionableEnd() == null ? 0 : gcGrouperSyncMember.getProvisionableEnd().getTime()); - targetEndMillis = Math.max(targetEndMillis, gcGrouperSyncMember.getLastUpdated() == null ? 0 : gcGrouperSyncMember.getLastUpdated().getTime()); - if (targetEndMillis != 0 &&( (System.currentTimeMillis() - targetEndMillis) / 1000 > removeSyncRowsAfterSecondsOutOfTarget)) { - gcGrouperSyncRowsToDeleteFromDatabase.add(gcGrouperSyncMember); - } - } - - } - - gcGrouperSync.getGcGrouperSyncMemberDao().memberDelete(gcGrouperSyncRowsToDeleteFromDatabase, true, true); - } - - // fix missing subject id or source id - Set gcGrouperSyncRowsToFixSubjectIdOrSourceId = new HashSet(); - for (GcGrouperSyncMember gcGrouperSyncMember : GrouperUtil.nonNull(memberUuidToSyncMember).values()) { - if (gcGrouperSyncRowsToDeleteFromDatabase.contains(gcGrouperSyncMember)) { - continue; - } - if (GrouperClientUtils.isBlank(gcGrouperSyncMember.getSourceId()) || GrouperClientUtils.isBlank(gcGrouperSyncMember.getSubjectId())) { - gcGrouperSyncRowsToFixSubjectIdOrSourceId.add(gcGrouperSyncMember); - } - } - - // null subject id issue - // GRP-4137: error resolving subject attributes. has null subject id and subject identifier - for (GcGrouperSyncMember gcGrouperSyncMember : gcGrouperSyncRowsToFixSubjectIdOrSourceId) { - - // try by query - GrouperProvisioningObjectAttributes grouperProvisioningObjectAttributes = memberUuidToProvisioningObjectAttributes.get(gcGrouperSyncMember.getMemberId()); - - decorateSyncMemberSubjectInformationIfNull(grouperProvisioner, gcGrouperSyncMember, - grouperProvisioningObjectAttributes); - } - - if (GrouperUtil.length(memberIdsToInsert) > 0) { - - Map mapMemberIdToSyncMemberInsert = gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveOrCreateByMemberIds(memberIdsToInsert); - - for (String memberIdToInsert : mapMemberIdToSyncMemberInsert.keySet()) { - - GcGrouperSyncMember gcGrouperSyncMember = mapMemberIdToSyncMemberInsert.get(memberIdToInsert); - initialGcGrouperSyncMembers.add(gcGrouperSyncMember); - GrouperProvisioningObjectAttributes grouperProvisioningObjectAttributes = memberUuidToProvisioningObjectAttributes.get(memberIdToInsert); - - if (grouperProvisioningObjectAttributes == null) { - continue; - } - String sourceId = grouperProvisioningObjectAttributes.getSourceId(); - String subjectId = grouperProvisioningObjectAttributes.getSubjectId(); - String subjectIdentifier = grouperProvisioningObjectAttributes.getSubjectIdentifier0(); - if ("subjectIdentifier1".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - subjectIdentifier = grouperProvisioningObjectAttributes.getSubjectIdentifier1(); - } else if ("subjectIdentifier2".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - subjectIdentifier = grouperProvisioningObjectAttributes.getSubjectIdentifier2(); - } - String metadataJson = grouperProvisioningObjectAttributes.getProvisioningMetadataJson(); - - if (gcGrouperSyncMember == null) { - gcGrouperSyncMember = gcGrouperSync.getGcGrouperSyncMemberDao().memberCreateByMemberId(memberIdToInsert); - } - - gcGrouperSyncMember.setSourceId(sourceId); - gcGrouperSyncMember.setSubjectId(subjectId); - gcGrouperSyncMember.setSubjectIdentifier(subjectIdentifier); -// gcGrouperSyncMember.setProvisionable(true); -// gcGrouperSyncMember.setProvisionableStart(new Timestamp(System.currentTimeMillis())); - gcGrouperSyncMember.setMetadataJson(metadataJson); - memberUuidToSyncMember.put(memberIdToInsert, gcGrouperSyncMember); - - } - - } - -// Set memberIdsToDelete = new HashSet(memberUuidToSyncMember.keySet()); -// -// provisioningSyncResult.setMemberIdsToDelete(memberIdsToDelete); -// -// memberIdsToDelete.removeAll(memberUuidToProvisioningObjectAttributes.keySet()); -// -// processSyncMemberDelete(memberUuidToSyncMember, memberIdsToDelete); - - } - - public static void decorateSyncMemberSubjectInformationIfNull(GrouperProvisioner grouperProvisioner, - GcGrouperSyncMember gcGrouperSyncMember, - GrouperProvisioningObjectAttributes grouperProvisioningObjectAttributes) { - if (grouperProvisioningObjectAttributes != null) { - String sourceId = grouperProvisioningObjectAttributes.getSourceId(); - String subjectId = grouperProvisioningObjectAttributes.getSubjectId(); - String subjectIdentifier = grouperProvisioningObjectAttributes.getSubjectIdentifier0(); - if ("subjectIdentifier1".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - subjectIdentifier = grouperProvisioningObjectAttributes.getSubjectIdentifier1(); - } else if ("subjectIdentifier2".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - subjectIdentifier = grouperProvisioningObjectAttributes.getSubjectIdentifier2(); - } - - if (GrouperClientUtils.isBlank(gcGrouperSyncMember.getSourceId())) { - gcGrouperSyncMember.setSourceId(sourceId); - } - - if (GrouperClientUtils.isBlank(gcGrouperSyncMember.getSubjectId())) { - gcGrouperSyncMember.setSubjectId(subjectId); - } - - if (GrouperClientUtils.isBlank(gcGrouperSyncMember.getSubjectIdentifier())) { - gcGrouperSyncMember.setSubjectIdentifier(subjectIdentifier); - } - } - - // TODO batch this when the API is available - if (GrouperClientUtils.isBlank(gcGrouperSyncMember.getSourceId()) || GrouperClientUtils.isBlank(gcGrouperSyncMember.getSubjectId())) { - Member member = MemberFinder.findByUuid(GrouperSession.staticGrouperSession(), gcGrouperSyncMember.getMemberId(), false); - if (member != null) { - if (GrouperClientUtils.isBlank(gcGrouperSyncMember.getSourceId())) { - gcGrouperSyncMember.setSourceId(member.getSubjectSourceId()); - } - if (GrouperClientUtils.isBlank(gcGrouperSyncMember.getSubjectId())) { - gcGrouperSyncMember.setSubjectId(member.getSubjectId()); - } - } - } - } - - - public static void fullSyncMembersForInitialize(GrouperProvisioner grouperProvisioner, ProvisioningSyncResult provisioningSyncResult, GcGrouperSync gcGrouperSync, - List initialGcGrouperSyncMembers, - Map memberUuidToProvisioningEntityWrapper) { - - initialGcGrouperSyncMembers = GrouperUtil.nonNull(initialGcGrouperSyncMembers); - - Map memberUuidToSyncMember = new HashMap(); - - for (GcGrouperSyncMember gcGrouperSyncMember : initialGcGrouperSyncMembers) { - memberUuidToSyncMember.put(gcGrouperSyncMember.getMemberId(), gcGrouperSyncMember); - } - - provisioningSyncResult.setGcGrouperSync(gcGrouperSync); - - // start group ids to insert with all group ids minus those which have sync group objects already - Set memberIdsToInsert = new HashSet(memberUuidToProvisioningEntityWrapper.keySet()); - provisioningSyncResult.setMemberIdsToInsert(memberIdsToInsert); - memberIdsToInsert.removeAll(memberUuidToSyncMember.keySet()); - - Set memberIdsToUpdate = new HashSet(); - provisioningSyncResult.setMemberIdsToUpdate(memberIdsToUpdate); - - Set memberIdsWithChangedSubjectIds = new HashSet(); - provisioningSyncResult.setMemberIdsWithChangedSubjectIds(memberIdsWithChangedSubjectIds); - - // lets remove ones that dont need to be there - if (GrouperUtil.length(memberUuidToSyncMember) > 0) { - - // make an array list so we can remove from the map without exception - List gcGrouperSyncMembers = new ArrayList(memberUuidToSyncMember.values()); - - for (GcGrouperSyncMember gcGrouperSyncMember : gcGrouperSyncMembers) { - - ProvisioningEntityWrapper provisioningEntityWrapper = memberUuidToProvisioningEntityWrapper.get(gcGrouperSyncMember.getMemberId()); - - ProvisioningEntity grouperProvisioningEntity = provisioningEntityWrapper == null ? null : provisioningEntityWrapper.getGrouperProvisioningEntity(); - - // keep it - if (grouperProvisioningEntity != null || gcGrouperSyncMember.isProvisionable() || gcGrouperSyncMember.isInTarget()) { - - if (grouperProvisioningEntity != null && StringUtils.isBlank(gcGrouperSyncMember.getSubjectId())) { - gcGrouperSyncMember.setSubjectId(grouperProvisioningEntity.getSubjectId()); - } - if (grouperProvisioningEntity != null && StringUtils.isBlank(gcGrouperSyncMember.getSourceId())) { - gcGrouperSyncMember.setSourceId(grouperProvisioningEntity.getSubjectSourceId()); - } - - // see if needs to update - { - String newSubjectId = grouperProvisioningEntity == null ? null : grouperProvisioningEntity.retrieveAttributeValueString("subjectId"); - if (!StringUtils.equals(newSubjectId, gcGrouperSyncMember.getSubjectId())) { - memberIdsWithChangedSubjectIds.add(gcGrouperSyncMember.getMemberId()); - } - } - - { - String newSubjectIdentifier = grouperProvisioningEntity == null ? null : grouperProvisioningEntity.retrieveAttributeValueString("subjectIdentifier0"); - if ("subjectIdentifier1".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - newSubjectIdentifier = grouperProvisioningEntity == null ? null : grouperProvisioningEntity.retrieveAttributeValueString("subjectIdentifier1"); - } else if ("subjectIdentifier2".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - newSubjectIdentifier = grouperProvisioningEntity == null ? null : grouperProvisioningEntity.retrieveAttributeValueString("subjectIdentifier2"); - } - - if (!StringUtils.equals(newSubjectIdentifier, gcGrouperSyncMember.getSubjectIdentifier())) { - if (grouperProvisioningEntity == null && gcGrouperSyncMember.isInTarget() && newSubjectIdentifier == null) { - // don't remove the identifier if not provisionable but still in target - } else { - gcGrouperSyncMember.setSubjectIdentifier(newSubjectIdentifier); - } - } - } - - // see if not provisionable - if (!gcGrouperSyncMember.isProvisionable() && grouperProvisioningEntity != null - && (provisioningEntityWrapper == null || !provisioningEntityWrapper.isDelete())) { - gcGrouperSyncMember.setProvisionableStart(new Timestamp(System.currentTimeMillis())); - gcGrouperSyncMember.setProvisionableEnd(null); - gcGrouperSyncMember.setProvisionable(true); - } - if (gcGrouperSyncMember.isProvisionable() && grouperProvisioningEntity == null) { - gcGrouperSyncMember.setProvisionableEnd(new Timestamp(System.currentTimeMillis())); - gcGrouperSyncMember.setProvisionable(false); - } - - // see if not provisionable - if (!gcGrouperSyncMember.isInTarget() && grouperProvisioningEntity != null - && (provisioningEntityWrapper == null || !provisioningEntityWrapper.isDelete())) { - memberIdsToInsert.add(gcGrouperSyncMember.getMemberId()); - } - - if (gcGrouperSyncMember.dbVersionDifferent()) { - memberIdsToUpdate.add(gcGrouperSyncMember.getMemberId()); - } - - continue; - } - - if (grouperProvisioningEntity == null && !gcGrouperSyncMember.isProvisionable() && !gcGrouperSyncMember.isInTarget() && gcGrouperSyncMember.getSubjectIdentifier() != null) { - gcGrouperSyncMember.setSubjectIdentifier(null); - } - - memberUuidToSyncMember.remove(gcGrouperSyncMember.getMemberId()); - - } - - } - - if (GrouperUtil.length(memberIdsToInsert) > 0) { - - Map mapMemberIdToSyncMemberInsert = gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveOrCreateByMemberIds(memberIdsToInsert); - - for (String memberIdToInsert : mapMemberIdToSyncMemberInsert.keySet()) { - - GcGrouperSyncMember gcGrouperSyncMember = mapMemberIdToSyncMemberInsert.get(memberIdToInsert); - ProvisioningEntityWrapper provisioningEntityWrapper = memberUuidToProvisioningEntityWrapper.get(memberIdToInsert); - ProvisioningEntity grouperProvisioningEntity = provisioningEntityWrapper == null ? null : provisioningEntityWrapper.getGrouperProvisioningEntity(); - - if (grouperProvisioningEntity == null) { - continue; - } - if (gcGrouperSyncMember == null) { - gcGrouperSyncMember = gcGrouperSync.getGcGrouperSyncMemberDao().memberCreateByMemberId(memberIdToInsert); - } - - gcGrouperSyncMember.setSourceId(grouperProvisioningEntity.retrieveAttributeValueString("subjectSourceId")); - gcGrouperSyncMember.setSubjectId(grouperProvisioningEntity.getSubjectId()); - - String subjectIdentifier = grouperProvisioningEntity.retrieveAttributeValueString("subjectIdentifier0"); - if ("subjectIdentifier1".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - subjectIdentifier = grouperProvisioningEntity.retrieveAttributeValueString("subjectIdentifier1"); - } else if ("subjectIdentifier2".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - subjectIdentifier = grouperProvisioningEntity.retrieveAttributeValueString("subjectIdentifier2"); - } - - gcGrouperSyncMember.setSubjectIdentifier(subjectIdentifier); - gcGrouperSyncMember.setProvisionable(true); - gcGrouperSyncMember.setProvisionableStart(new Timestamp(System.currentTimeMillis())); - memberUuidToSyncMember.put(memberIdToInsert, gcGrouperSyncMember); - provisioningEntityWrapper.setGcGrouperSyncMember(gcGrouperSyncMember); - - } - - } - - Set memberIdsToDelete = new HashSet(memberUuidToSyncMember.keySet()); - - provisioningSyncResult.setMemberIdsToDelete(memberIdsToDelete); - - memberIdsToDelete.removeAll(memberUuidToProvisioningEntityWrapper.keySet()); - - if (GrouperUtil.length(memberIdsToDelete) > 0) { - - Iterator memberIdToDeleteIterator = memberIdsToDelete.iterator(); - - while (memberIdToDeleteIterator.hasNext()) { - - String memberIdToDelete = memberIdToDeleteIterator.next(); - - GcGrouperSyncMember gcGrouperSyncMember = memberUuidToSyncMember.get(memberIdToDelete); - - if (gcGrouperSyncMember == null) { - throw new RuntimeException("why is gcGrouperSyncMember null???"); - } - - if (gcGrouperSyncMember.isProvisionable() || gcGrouperSyncMember.getProvisionableEnd() == null) { - gcGrouperSyncMember.setProvisionable(false); - gcGrouperSyncMember.setProvisionableEnd(new Timestamp(System.currentTimeMillis())); - } - - // if we arent in target, dont worry about it - if (!gcGrouperSyncMember.isInTarget() ) { - memberIdToDeleteIterator.remove(); - memberUuidToSyncMember.remove(gcGrouperSyncMember.getMemberId()); - } - - } - - } - - } - - - public static void fullSyncMemberships(ProvisioningSyncResult provisioningSyncResult, GcGrouperSync gcGrouperSync, - List initialGcGrouperSyncGroups, List initialGcGrouperSyncMembers, - List initialGcGrouperSyncMemberships, Map groupIdMemberIdToProvisioningMembershipWrapper) { - - if (gcGrouperSync == null || StringUtils.isBlank(gcGrouperSync.getProvisionerName())) { - throw new RuntimeException("provisioner name is required"); - } - - if (!GrouperProvisioningSettings.getTargets(true).containsKey(gcGrouperSync.getProvisionerName())) { - throw new RuntimeException("Target '" + gcGrouperSync.getProvisionerName() - + "' is not configured. Go to Miscellaneous -> Provisioning to configure a new target."); - } - - initialGcGrouperSyncMemberships = GrouperUtil.nonNull(initialGcGrouperSyncMemberships); - - Map groupSyncIdToSyncGroup = new HashMap(); - for (GcGrouperSyncGroup gcGrouperSyncGroup : GrouperUtil.nonNull(initialGcGrouperSyncGroups)) { - groupSyncIdToSyncGroup.put(gcGrouperSyncGroup.getId(), gcGrouperSyncGroup); - } - Map memberSyncIdToSyncMember = new HashMap(); - for (GcGrouperSyncMember gcGrouperSyncMember : GrouperUtil.nonNull(initialGcGrouperSyncMembers)) { - memberSyncIdToSyncMember.put(gcGrouperSyncMember.getId(), gcGrouperSyncMember); - } - - Map groupIdMemberIdToSyncMembership = new HashMap(); - - for (GcGrouperSyncMembership gcGrouperSyncMembership : initialGcGrouperSyncMemberships) { - - GcGrouperSyncGroup gcGrouperSyncGroup = groupSyncIdToSyncGroup.get(gcGrouperSyncMembership.getGrouperSyncGroupId()); - GcGrouperSyncMember gcGrouperSyncMember = memberSyncIdToSyncMember.get(gcGrouperSyncMembership.getGrouperSyncMemberId()); - if (gcGrouperSyncGroup != null && gcGrouperSyncMember != null) { - groupIdMemberIdToSyncMembership.put( - new MultiKey(gcGrouperSyncGroup.getGroupId(), gcGrouperSyncMember.getMemberId()), gcGrouperSyncMembership); - } - } - - int removeSyncRowsAfterSecondsOutOfTarget = GrouperLoaderConfig.retrieveConfig().propertyValueInt( - "grouper.provisioning.removeSyncRowsAfterSecondsOutOfTarget", 60*60*24*7); - - provisioningSyncResult.setGcGrouperSync(gcGrouperSync); - - // start group ids to insert with all group ids minus those which have sync group objects already - Set groupIdMemberIdsToInsert = new HashSet(groupIdMemberIdToProvisioningMembershipWrapper.keySet()); - provisioningSyncResult.setMembershipGroupIdMemberIdsToInsert(groupIdMemberIdsToInsert); - groupIdMemberIdsToInsert.removeAll(groupIdMemberIdToSyncMembership.keySet()); - - Set groupIdMemberIdsToUpdate = new HashSet(); - provisioningSyncResult.setMembershipGroupIdMemberIdsToUpdate(groupIdMemberIdsToUpdate); - - List gcGrouperSyncRowsToDeleteFromDatabase = new ArrayList(); - - // lets remove ones that dont need to be there - if (GrouperUtil.length(groupIdMemberIdToSyncMembership) > 0) { - Set groupIdMemberIds = new HashSet(groupIdMemberIdToSyncMembership.keySet()); - for (MultiKey groupIdMemberId : groupIdMemberIds) { - - GcGrouperSyncMembership gcGrouperSyncMembership = groupIdMemberIdToSyncMembership.get(groupIdMemberId); - - GcGrouperSyncGroup gcGrouperSyncGroup = groupSyncIdToSyncGroup.get(gcGrouperSyncMembership.getGrouperSyncGroupId()); - - GcGrouperSyncMember gcGrouperSyncMember = memberSyncIdToSyncMember.get(gcGrouperSyncMembership.getGrouperSyncMemberId()); - - // not sure why this would happen, i guess if a group aged out and this is already removed???? - if (gcGrouperSyncGroup == null || gcGrouperSyncMember == null) { - continue; - } - - ProvisioningMembershipWrapper provisioningMembershipWrapper = groupIdMemberIdToProvisioningMembershipWrapper.get(groupIdMemberId); - - ProvisioningMembership grouperProvisioningMembership = provisioningMembershipWrapper == null ? null : provisioningMembershipWrapper.getGrouperProvisioningMembership(); - - // keep it - boolean membershipProvisionable = gcGrouperSyncGroup.isProvisionable() && gcGrouperSyncMember.isProvisionable(); - - if (grouperProvisioningMembership != null || membershipProvisionable || gcGrouperSyncMembership.isInTarget()) { - - // see if not provisionable - if (!gcGrouperSyncMembership.isInTarget() && grouperProvisioningMembership != null - && (provisioningMembershipWrapper == null || provisioningMembershipWrapper.isDelete())) { - groupIdMemberIdsToInsert.add(groupIdMemberId); - } - - if (gcGrouperSyncMembership.dbVersionDifferent()) { - groupIdMemberIdsToUpdate.add(groupIdMemberId); - } - - continue; - } - - groupIdMemberIdToSyncMembership.remove(groupIdMemberId); - - - if (!gcGrouperSyncMembership.isInTarget() && gcGrouperSyncMembership.getInTargetEnd() != null) { - //if we arent provisionable, and the group has not been in the target for a week, then we done with that one - long targetEndMillis = gcGrouperSyncMembership.getInTargetEnd() == null ? 0 : gcGrouperSyncMembership.getInTargetEnd().getTime(); - targetEndMillis = Math.max(targetEndMillis, gcGrouperSyncMembership.getLastUpdated() == null ? 0 : gcGrouperSyncMembership.getLastUpdated().getTime()); - //if we arent provisionable, and the group has not been in the target for a week, then we done with that one - if (targetEndMillis != 0 &&( (System.currentTimeMillis() - targetEndMillis) / 1000 > removeSyncRowsAfterSecondsOutOfTarget)) { - gcGrouperSyncRowsToDeleteFromDatabase.add(gcGrouperSyncMembership); - } - } - } - - gcGrouperSync.getGcGrouperSyncMembershipDao().membershipDelete(gcGrouperSyncRowsToDeleteFromDatabase, true); - } - - if (GrouperUtil.length(groupIdMemberIdsToInsert) > 0) { - - Map mapGroupIdMemberIdToSyncMembershipInsert = gcGrouperSync.getGcGrouperSyncMembershipDao() - .membershipRetrieveOrCreateByGroupIdsAndMemberIds(gcGrouperSync.getId(), groupIdMemberIdsToInsert); - - for (MultiKey groupIdMemberIdToInsert : mapGroupIdMemberIdToSyncMembershipInsert.keySet()) { - - GcGrouperSyncMembership gcGrouperSyncMembership = mapGroupIdMemberIdToSyncMembershipInsert.get(groupIdMemberIdToInsert); - ProvisioningMembershipWrapper provisioningMembershipWrapper = groupIdMemberIdToProvisioningMembershipWrapper.get(groupIdMemberIdToInsert); - ProvisioningMembership grouperProvisioningMembership = provisioningMembershipWrapper == null ? null : provisioningMembershipWrapper.getGrouperProvisioningMembership(); - - if (grouperProvisioningMembership == null) { - continue; - } - if (gcGrouperSyncMembership == null) { - gcGrouperSyncMembership = gcGrouperSync.getGcGrouperSyncMembershipDao().membershipCreateBySyncGroupIdAndSyncMemberId((String)groupIdMemberIdToInsert.getKey(0), - (String)groupIdMemberIdToInsert.getKey(1)); - } - groupIdMemberIdToSyncMembership.put(groupIdMemberIdToInsert, gcGrouperSyncMembership); - provisioningMembershipWrapper.setGcGrouperSyncMembership(gcGrouperSyncMembership); - - } - - } - - Set groupIdMemberIdsToDelete = new HashSet(groupIdMemberIdToSyncMembership.keySet()); - - provisioningSyncResult.setMembershipGroupIdMemberIdsToDelete(groupIdMemberIdsToDelete); - - groupIdMemberIdsToDelete.removeAll(groupIdMemberIdToProvisioningMembershipWrapper.keySet()); - - if (GrouperUtil.length(groupIdMemberIdsToDelete) > 0) { - - Iterator groupIdMemberIdToDeleteIterator = groupIdMemberIdsToDelete.iterator(); - - while (groupIdMemberIdToDeleteIterator.hasNext()) { - - MultiKey groupIdMemberIdToDelete = groupIdMemberIdToDeleteIterator.next(); - - GcGrouperSyncMembership gcGrouperSyncMembership = groupIdMemberIdToSyncMembership.get(groupIdMemberIdToDelete); - - if (gcGrouperSyncMembership == null) { - throw new RuntimeException("why is gcGrouperSyncMembership null???"); - } - - // if we arent in target, dont worry about it - if (!gcGrouperSyncMembership.isInTarget() ) { - groupIdMemberIdToDeleteIterator.remove(); - groupIdMemberIdToSyncMembership.remove(groupIdMemberIdToDelete); - } - - } - - } - - } - -} diff --git a/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$1.class b/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$1.class deleted file mode 100644 index 1cd57b07a9e4375ca7108a54e73ea3a3bfbefc24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4766 zcmb_g`&S%i8GgQDVU}eAgd~t{8oN!gfemCsY!d^RO1QMx4UHk8rqP;VcUU%EX2{Ge zO=@kuRjW~3Z`IU$y`I zBbDZtB*qQL$y?^=%xs~(M@2-S`Mf@-rwY26OFb}o-pIHr>I8bK!T^}Wz(+ll#&A4ID8TM#ape4N~?YL{_%^cTha-C!7c4m6W6xg=5 zO%9D`tXV_gaFsI26ODUV-bTX5B;HiMKwS%Ll^?oG){{lo7}IA6-6+Rw!!6q8sY{aA z){vBg1>JFoQrDk1^X^fBe{@tS$)?%~aR~HKVWc`Ml%Kc)&^o1u*7yhPoDhf%T3MqW z0<9WUL?yLTLp@@Wx?VF2wh4C7uEBLeY~ zqlFKjF`qn7CPpY))L{RPNk%mVmOTtX*h$2SYIgq zz)H#&IM5MNVqo1eHAX~UHm9b`Km<0R^?8BX= zwjB*RCRsO(3q`#^z3r{Qwt^rJNy)Ps3`_~sQgT@mOJgsPIfiMRSCOx#*n76R*Y7N( zbQ&H(fyQuI?*?_pWql2c7i77RctMp2jRb2NU}9E<#WK2PE$L($E`Ua^(X*`kJ1U@e z@~AH6R1_;^&sFtncvSje6IJ0Kd_pf24M%#(B@K_^V@y)hx-&+H@M;ZF`|)uNPvFV5 z#Ly$Khu&7nY*sGEHYAm{a`e1U;?pWV#mct%N)4Zpd>ix5kTF@z4V$upWmSBZ$Qn$BujD|CF30L~=Hz-rW_A-K#n6m7I6Le#}o*dtlaNiQ>4qIqN zj*z*_VV`GQbrH+&+IkaFd`F<6E8#aXuZx?yX&WbuttoB`U`43nd2w=?^ zE7D1UrtyM?AK}MTu50-`M=YDhDGQ*$`zoBgPb%rB8m`I!imrf2)Ba4u&+!XJRaP3U zO!Wbv*Q&_U5GsXlulWpZWSbC?SWK~{X*yKAsYYLke$p1$Rk}2sj)_<2Tavo-ZQ}*D z3^&fz8Zz@y>7@v(Igv~1S4}{_S-)&G=(x1WWOF=f$`;vSrlSWou5R{1u(X>G^v8r; z+SW0_1g+i4DtkI9Z%B!o^*yvg>W4DSvMq75SSH4 z-l?8rJ#>&1#bBnw;cyHbsyf^O*-kUcD@6G#y z_vUSZ_hN;=7HlKRc2X1kCJMTe`{uDD*)@;0WcNJc$#`TQyOQzRdF)Qc>*jG=GOo_! z_T+Wk@v?_2Le=Zb^UFr+J#^TE5RmJkp$9 z#1Ba=;3rFXQ9(TNlBZs2iigogh5j2+@gH=HWgMcNPbdOsl^PV32ppvrPbhVGT2XOX zsmHTQj1U@LQMO=FX~Y}+{u}qarR=~zl~&QDw26eWQyd|ERN3X3c*-|gU}BmNzr?R- z+^9H$U*k74Z@1Wvm+&$Te@Haow|IrdKY_<_4fAx`vusoraGj3pU;JI|nQ8ADK22o(oa99A)`vW~0lRIrQ@M9XGW zoaUU$CWzD95ZiFtL)f!SX*L4CfZDR%o(cZIr$Qg}z5I`O!yE0#pKy~@j7N~s!N30j D$)Rnq diff --git a/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$10.class b/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$10.class deleted file mode 100644 index ebfddc755d79d2d2ea3941e3142a3e8644ae5dad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1829 zcmb_dT~pIQ6g}J421>BytDuOYR&5IsKoPNsT0~{6GGiSc`sB7*N-%6XNs9WfbVmGo zaD4Vx_~PGiyjzN;P=eXs@o+^%G z8>_q1gb&YK(()G=%;ZTBI5Jvll_9j~n4%L5Q5_mOl+~l76Ojml=+n`KeuiLDL8CcK zis#kMqHtgGqAeJDb54odtK79zzdjgJ8Dw~T0`#f8l#&jLVHbJnHN(?(ld`9#S;1u{ zm1|W9IgTv7EeR@~BRvfx41EpEzZr(kyj7Omue!A1wPVJgZ?40lBPEHH0%sNuq87nL zT-I=jVWvG1wrp2N0#_KcvhdXmLx1vs1ZcR%FxVu=2C*)rFs32RFx-S_7OakOT&D`v z1x^_nNbb*cst|#JDGhY2dKx*-lJ==KI;L@h$dZq$SXpC;CkuPo)?rkys5)!)ld7u9 zFx#fcTJl4_;?2^1SJ{>Ci{rUGs=}nSyi;{c;*q6J&5&Z#a*<7_v@pEdpS=I4b2OFc zk}TPdXUXz2;jcTUhPw>e_GG5=f7o58;~wraoc4w1H)PZzh`jGo;7qE(pfA%Ia2IXv zdBVde-8(^Qrx1w6)I|iudet>V|BC>%F6cDdP1YRsgY=E2$F^}gJ-&@t`ZIbz)PMu@ z4igZeUx<^f77-MK7@{x38JwlX!(@l3cMj*t3gAM`ae*uqsz3b^v9V7W{ei1rkqqDq zCf?I{5Do9YYu@8K__}vmNx!xk@_UQWJCW7MERBS4yB2A#9`Oz`)DK}E3wS_QgfNOJ GJ%0fz*%!0` diff --git a/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$2.class b/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$2.class deleted file mode 100644 index c4d3cefb926f52bf998311609685da101daa731d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4916 zcmb_g`FGUT8NE*)TjQ|+Ed!=3O(M^T@xWM`N*V%A z+oWkq_kE#B*Q5(=x+N_(c4%n2(Ink|$PfK*O7D|okH$7Wlb-mTkv=^=-EV#Oea~Phhx_$QlG@~z5qoLonEG~BH z@7=qYg$ZoMHWlv^*j|4bMZDIq9XkZng6YY42;AMVNE}q`5?FHw!&Ibe=qV`l1p2U7 z#U6qE^%=I*I@0idJjg5?xg3d++$9qAhIc90-blu0m**XvTx@E6e#x*#nQEcV(+h_p zBN?0Q*;!i^0p3y5t(3f875m9${@Sm2#Zu~^;f@_P$_ea4djf+vpkhcsuW>92py42f zS?Mf+L5qxOa$&BWtpXph-!7HHB5c7S99EHGp;R?i-)lI6hnc7%S=jJwGV$sfq~UP9 zw*?e{BLltNCt%hT=C}Wm+k=qVaG4nDleVzNFH-RF~t2nn956#WeP?GsvL0tjnh*7GTZUPp{ zD(rfi20!Zuf)3?4Yf8gMz+A>X?wkFF%W&+Bn!Yd`;cl}qKrQfaK}ChzaW&R5Wf~sG zMF!i*vwv8%2zuu!Su+zFp1?;*SYw8JgyrGyJEtVsd|bnmc&bVgTLkW7?a9h9%0_O? zOy%tHaq@VoWETo-Nm3cRz&d;yq$ce$l!YWS4YyS(TQn4^`#pe1*+yoyhg7=2It z)+`A4{z|cwH=Q^>%Z6geu2}hG0+;c5xl?{&o_DipACXn~B@JK3S6KOOae{jYx71g8=rpIcsy8;j-`(4L`+IhTO9QtA=ccDHGTj^&zaiMdHELav49@@S-Gu z_$-J__%Aj53cn^R+BV! zN0HDk)lZStBR(>CeG67XxbORfD1*><>?j+ty>w?)75JB-HL_jqYP0Hv-2ReBd=)xx2+D$peryisz zDcCHvDsRvt+9>vHn!=XXu=8-&H7dV`HQl`E{H^0}L+n-TKG{I&o~)Qg?~xnWck(*= z)3JsfjXhHsn88B=Y4s{5bae(F5O@v8(@i&Ug0oJh<9gE+PNkdmnBJ_%XYfb^PUuY% zZ3_8xLQmYnemyaTu>eN9icVegVbU#n3+LTCjd3a7LhCb)LXYb$GjJ7xa25&Xx!Z3^ zwZ8Q9G(I+iPY67Va};mj^2xT(T*v41*bKfXFomzSeRB#|Ry9iLIZA|I!&}>T16h~y z_XBx@lz$k=H1$f`3%uyD*8DVnOlb-~o53#>=&_gl(8@GCf;9~4F2t2IdXzrwQ1)QA zvKLw9L7Y+cA*b}iRt7Pl9Ke&xL0nND!VAhFTval7Q8|oj9J|T+uPa%+r5qD2%5kw? z84=qlri5BSkGj#>He<5yw z@mFHp;;acY-o^pMRZubijkHt6po&M?J+YI*Z46=A{8uWD^Q8**-MdwGoBquEZ_|`J lqCA17`6$#K!{2yS@OoI_Z{SUTv=4vBzbGYWw_F(f`yaPHpez6Y diff --git a/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$3.class b/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$3.class deleted file mode 100644 index 836d9b6096d0d29695900a83e09a4187cae7b373..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2947 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 diff --git a/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$5.class b/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$5.class deleted file mode 100644 index 18ffae4efc6d25ffa38595219706e9cbf1777e22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3018 zcmb_e>r)$56#v~Nur%EY1zJcgw$)&h@Ce0XZGu>N32gv*2*p}ulU%~WvYT!;(E8DT zreAeN9u=qUjE_;r@lO)ZNg^bHVC)noyXW3L_dI{+ocqV$KRgF;6B!kXz=%v{!-nNb z$C7Sec*960O}V8zGMsYkY+5>DGpVO@57*d~;TWx$n3I`|VOtX$Y17}Y!XwbQrf=$D zQ@2v#>G+yVxGL%dZd50q#g6M1>2?I_+*Kpv?fu0jM${=tkIhT)N%xRd%X9RfpSSGSA6>7N5m4ca6Y$YBX zhKXaksNp{MyxN3mXQYbH36e*Byr?5I@GK}y5^gdAx2kM;Wpzp*@~|vQV5wb4Wk4*A ziNki0$A-X_O6&#jkP|GokL1TGNtD{s10@h36&Fj}`IGd&Eq(UY96PPwQ7z25)YK>S zbZ%~_SS<PDQ1wgN8I7(d9tTx~p6*37z44`=lB;!eXIrio8CoBoZ}2!^Igk z>82qwxJqNahJLlEX>8<)4>UIMywAO9+S5Hvp`V6x#PtSIgS7V0yCu}QjfPOyHqM8- zx6vHh#f9&3+->x%BW@^r@DZ&sjTT(OoAf5Ip`CQTMYM-jS8$Ce1#h!-@lDV0Q5-S|W9PhVCj)Q5#WxbuWsS;#;z(9n3Vwva^(WdfOE(U`X5x^?MfT;)g zg1oQC3LfH1^1q4JUy)X}WCl9zd1yXfMjQ#sPLfXN=E&X4YZS+Jg<)aES7fcFrjM{R73z BX{7)F diff --git a/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$6.class b/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$6.class deleted file mode 100644 index 003e1a8342dc8e8792d1f93a19425a115e1bf079..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4276 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 PpYb=gyj)h-694`Sc4!3w diff --git a/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$9.class b/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl$9.class deleted file mode 100644 index 4a47d433a188209cdfb1d4696df065ddd243c033..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5723 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 diff --git a/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl.java b/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl.java deleted file mode 100644 index 2d9a4054..00000000 --- a/container_files/api/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl.java +++ /dev/null @@ -1,1292 +0,0 @@ -/** - * Copyright 2014 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package edu.internet2.middleware.grouper.ldap.ldaptive; - -import java.io.IOException; -import java.net.URL; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import javax.net.ssl.SSLSocketFactory; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.ldaptive.AddOperation; -import org.ldaptive.AddRequest; -import org.ldaptive.AttributeModification; -import org.ldaptive.AttributeModificationType; -import org.ldaptive.BindConnectionInitializer; -import org.ldaptive.BindOperation; -import org.ldaptive.BindRequest; -import org.ldaptive.CompareRequest; -import org.ldaptive.Connection; -import org.ldaptive.ConnectionConfig; -import org.ldaptive.Credential; -import org.ldaptive.DefaultConnectionFactory; -import org.ldaptive.DeleteOperation; -import org.ldaptive.DeleteRequest; -import org.ldaptive.LdapAttribute; -import org.ldaptive.LdapEntry; -import org.ldaptive.LdapException; -import org.ldaptive.ModifyDnOperation; -import org.ldaptive.ModifyDnRequest; -import org.ldaptive.ModifyOperation; -import org.ldaptive.ModifyRequest; -import org.ldaptive.Response; -import org.ldaptive.ResultCode; -import org.ldaptive.SearchFilter; -import org.ldaptive.SearchOperation; -import org.ldaptive.SearchRequest; -import org.ldaptive.SearchResult; -import org.ldaptive.SearchScope; -import org.ldaptive.control.util.PagedResultsClient; -import org.ldaptive.handler.SearchEntryHandler; -import org.ldaptive.pool.BlockingConnectionPool; -import org.ldaptive.pool.CompareValidator; -import org.ldaptive.pool.IdlePruneStrategy; -import org.ldaptive.pool.PoolConfig; -import org.ldaptive.pool.PooledConnectionFactory; -import org.ldaptive.pool.SearchValidator; -import org.ldaptive.pool.Validator; -import org.ldaptive.props.BindConnectionInitializerPropertySource; -import org.ldaptive.props.ConnectionConfigPropertySource; -import org.ldaptive.props.DefaultConnectionFactoryPropertySource; -import org.ldaptive.props.PoolConfigPropertySource; -import org.ldaptive.props.SearchRequestPropertySource; -import org.ldaptive.provider.jndi.JndiProviderConfig; -import org.ldaptive.referral.AddReferralHandler; -import org.ldaptive.referral.DeleteReferralHandler; -import org.ldaptive.referral.ModifyDnReferralHandler; -import org.ldaptive.referral.ModifyReferralHandler; -import org.ldaptive.referral.SearchReferralHandler; -import org.ldaptive.sasl.GssApiConfig; - -import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; -import edu.internet2.middleware.grouper.ldap.LdapConfiguration; -import edu.internet2.middleware.grouper.ldap.LdapHandler; -import edu.internet2.middleware.grouper.ldap.LdapHandlerBean; -import edu.internet2.middleware.grouper.ldap.LdapModificationItem; -import edu.internet2.middleware.grouper.ldap.LdapModificationType; -import edu.internet2.middleware.grouper.ldap.LdapPEMSocketFactory; -import edu.internet2.middleware.grouper.ldap.LdapSearchScope; -import edu.internet2.middleware.grouper.ldap.LdapSession; -import edu.internet2.middleware.grouper.util.GrouperUtil; -import edu.internet2.middleware.morphString.Morph; -/** - * will handle the ldap config, and inverse of control for pooling - * - * @author mchyzer - * - */ -public class LdaptiveSessionImpl implements LdapSession { - - /** - * debug log where lines are separated by newlines - */ - private StringBuilder debugLog = null; - - /** - * debug log where lines are separated by newlines - * @return - */ - public StringBuilder getDebugLog() { - return debugLog; - } - - /** - * if we are debugging - */ - private boolean debug = false; - - /** - * if we are debugging - * @return - */ - public boolean isDebug() { - return debug; - } - - /** - * if we should capture debug info - * @param isDebug - */ - public void assignDebug(boolean isDebug, StringBuilder theDebugLog) { - this.debug = isDebug; - if (isDebug) { - this.debugLog = theDebugLog; - } else { - this.debugLog = null; - } - - } - - /** - * if we should capture debug info - * @param isDebug - */ - public void assignDebug(boolean isDebug) { - assignDebug(isDebug, new StringBuilder()); - } - - /** map of connection name to pool */ - private static Map poolMap = Collections.synchronizedMap(new HashMap()); - - /** map of connection name to properties */ - private static Map propertiesMap = Collections.synchronizedMap(new HashMap()); - - /** pools that need to be cleaned up */ - private static List poolsNeedingCleanup = new ArrayList(); - - /** - * What ldaptive properties will be decrypted if their values are Morph files? - * (We don't decrypt all properties because that would prevent the use of slashes in the property values) - **/ - public static final String ENCRYPTABLE_LDAPTIVE_PROPERTIES[] = new String[]{"org.ldaptive.bindCredential"}; - - private static Map>> searchEntryHandlers = Collections.synchronizedMap(new HashMap>>()); - - private static boolean hasWarnedAboutMissingDnAttributeForSearches = false; - - /** - * get or create the pool based on the server id - * @param ldapServerId - * @return the pool - */ - @SuppressWarnings("unchecked") - private static PooledConnectionFactory blockingLdapPool(String ldapServerId) { - - PooledConnectionFactory blockingLdapPool = poolMap.get(ldapServerId); - - if (blockingLdapPool == null) { - synchronized (LdaptiveSessionImpl.class) { - blockingLdapPool = poolMap.get(ldapServerId); - - if (blockingLdapPool == null) { - - BlockingConnectionPool result; - - Properties ldaptiveProperties = getLdaptiveProperties(ldapServerId); - propertiesMap.put(ldapServerId, ldaptiveProperties); - - boolean isActiveDirectory = LdapConfiguration.getConfig(ldapServerId).isActiveDirectory(); - - // search result handlers - LinkedHashSet> handlers = new LinkedHashSet>(); - String handlerNames = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".searchResultHandlers"); - if (StringUtils.isEmpty(handlerNames) && isActiveDirectory) { - handlerNames = "edu.internet2.middleware.grouper.ldap.ldaptive.GrouperRangeEntryHandler"; - } - - if (!StringUtils.isBlank(handlerNames)) { - String[] handlerClassNames = GrouperUtil.splitTrim(handlerNames, ","); - for (String className : handlerClassNames) { - if (className.equals("edu.internet2.middleware.grouper.ldap.handler.RangeSearchResultHandler")) { - className = "edu.internet2.middleware.grouper.ldap.ldaptive.GrouperRangeEntryHandler"; - } else if (className.equals("edu.vt.middleware.ldap.handler.EntryDnSearchResultHandler")) { - className = "org.ldaptive.handler.DnAttributeEntryHandler"; - } else if (className.equals("edu.vt.middleware.ldap.handler.FqdnSearchResultHandler")) { - // ldaptive already gives back the full dn so hopefully we don't have to do anything here. - continue; - } else if (className.equals("edu.vt.middleware.ldap.handler.BinarySearchResultHandler")) { - // ldaptive already handles binary attributes separately so maybe this isn't needed?? need to check - continue; - } - Class customClass = GrouperUtil.forName(className); - handlers.add(customClass); - } - } - - searchEntryHandlers.put(ldapServerId, handlers); - - // Setup ldaptive ConnectionConfig - ConnectionConfig connConfig = new ConnectionConfig(); - DefaultConnectionFactory connectionFactory = new DefaultConnectionFactory(); - - ConnectionConfigPropertySource ccpSource = new ConnectionConfigPropertySource(connConfig, ldaptiveProperties); - ccpSource.initialize(); - - ///////////// - // Binding - BindConnectionInitializer binder = new BindConnectionInitializer(); - - BindConnectionInitializerPropertySource bcip = new BindConnectionInitializerPropertySource(binder, ldaptiveProperties); - bcip.initialize(); - - // I'm not sure if SaslRealm and/or SaslAuthorizationId can be used independently - // Therefore, we'll initialize gssApiConfig when either one of them is used. - // And, then, we'll attach the gssApiConfig to the binder if there is a gssApiConfig - GssApiConfig gssApiConfig = null; - String val = (String) ldaptiveProperties.get("org.ldaptive.saslRealm"); - if (!StringUtils.isBlank(val)) { - LOG.info("Processing saslRealm"); - if ( gssApiConfig == null ) - gssApiConfig = new GssApiConfig(); - gssApiConfig.setRealm(val); - } - - val = (String) ldaptiveProperties.get("org.ldaptive.saslAuthorizationId"); - if (!StringUtils.isBlank(val)) { - LOG.info("Processing saslAuthorizationId"); - if ( gssApiConfig == null ) - gssApiConfig = new GssApiConfig(); - gssApiConfig.setAuthorizationId(val); - } - - // If there was a sasl/gssapi attribute, then save the gssApiConfig - if ( gssApiConfig != null ) { - LOG.info("Setting gssApiConfig"); - binder.setBindSaslConfig(gssApiConfig); - } - - // handle ssl socket factory - String cafile = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".pemCaFile"); - String certfile = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".pemCertFile"); - String keyfile = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".pemKeyFile"); - if (cafile != null && certfile != null && keyfile != null) { - LdapPEMSocketFactory sf = new LdapPEMSocketFactory(cafile, certfile, keyfile); - SSLSocketFactory ldapSocketFactory = sf.getSocketFactory(); - ((JndiProviderConfig) connectionFactory.getProvider().getProviderConfig()).setSslSocketFactory(ldapSocketFactory); - } - - connConfig.setConnectionInitializer(binder); - - DefaultConnectionFactoryPropertySource dcfSource = new DefaultConnectionFactoryPropertySource(connectionFactory, ldaptiveProperties); - dcfSource.initialize(); - connectionFactory.setConnectionConfig(connConfig); - - LinkedHashSet codesToIgnore = new LinkedHashSet(); - String searchIgnoreResultCodes = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".searchIgnoreResultCodes", "SIZE_LIMIT_EXCEEDED"); - if (!StringUtils.isBlank(searchIgnoreResultCodes)) { - String[] searchIgnoreResultCodesArray = GrouperUtil.splitTrim(searchIgnoreResultCodes, ","); - for (String searchIgnoreResultCode : searchIgnoreResultCodesArray) { - codesToIgnore.add(ResultCode.valueOf(searchIgnoreResultCode)); - } - } - ((JndiProviderConfig) connectionFactory.getProvider().getProviderConfig()).setSearchIgnoreResultCodes(codesToIgnore.toArray(new ResultCode[]{})); - - - // batch size - int batchSize = GrouperLoaderConfig.retrieveConfig().propertyValueInt("ldap." + ldapServerId + ".batchSize", -1); - if (batchSize > -1) { - connectionFactory.getProvider().getProviderConfig().getProperties().put("java.naming.batchsize", "" + batchSize); - } - - //((org.ldaptive.BindConnectionInitializer)connectionFactory.getConnectionConfig().getConnectionInitializer()).setBindDn(""); - - ///////////// - // PoolConfig - - PoolConfig ldapPoolConfig = new PoolConfig(); - PoolConfigPropertySource pcps = new PoolConfigPropertySource(ldapPoolConfig, ldaptiveProperties); - pcps.initialize(); - - result = new BlockingConnectionPool(ldapPoolConfig, connectionFactory); - - int pruneTimerPeriod = GrouperLoaderConfig.retrieveConfig().propertyValueInt("ldap." + ldapServerId + ".pruneTimerPeriod", 300000); - int expirationTime = GrouperLoaderConfig.retrieveConfig().propertyValueInt("ldap." + ldapServerId + ".expirationTime", 600000); - - int validateTimerPeriod = GrouperLoaderConfig.retrieveConfig().propertyValueInt("ldap." + ldapServerId + ".validateTimerPeriod", 0); - if (validateTimerPeriod > 0) { - ldapPoolConfig.setValidatePeriod(Duration.ofMillis(validateTimerPeriod)); - } - - IdlePruneStrategy idlePruneStrategy = new IdlePruneStrategy(); - idlePruneStrategy.setIdleTime(Duration.ofMillis(expirationTime)); - idlePruneStrategy.setPrunePeriod(Duration.ofMillis(pruneTimerPeriod)); - result.setPruneStrategy(idlePruneStrategy); - - Validator validator = retrieveValidator(ldapServerId); - - if (validator != null) { - result.setValidator(validator); - - // Make sure some kind of validation is turned on - if ( !ldapPoolConfig.isValidateOnCheckIn() && - !ldapPoolConfig.isValidateOnCheckOut() && - !ldapPoolConfig.isValidatePeriodically() ) { - ldapPoolConfig.setValidatePeriodically(true); - } - } - - result.initialize(); - - blockingLdapPool = new PooledConnectionFactory(result); - - poolMap.put(ldapServerId, blockingLdapPool); - } - } - } - return blockingLdapPool; - } - - private static Validator retrieveValidator(String ldapServerId) { - - Validator validator = null; - - String ldapValidator = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".validator", "SearchValidator"); - - if (StringUtils.equalsIgnoreCase(ldapValidator, CompareValidator.class.getSimpleName()) - || StringUtils.equalsIgnoreCase(ldapValidator, "CompareLdapValidator")) { - String validationDn = GrouperLoaderConfig.retrieveConfig().propertyValueStringRequired("ldap." + ldapServerId + ".validatorCompareDn"); - String validationAttribute = GrouperLoaderConfig.retrieveConfig().propertyValueStringRequired("ldap." + ldapServerId + ".validatorCompareAttribute"); - String validationValue = GrouperLoaderConfig.retrieveConfig().propertyValueStringRequired("ldap." + ldapServerId + ".validatorCompareValue"); - validator = new CompareValidator(new CompareRequest(validationDn, new LdapAttribute(validationAttribute, validationValue))); - } else if (StringUtils.equalsIgnoreCase(ldapValidator, SearchValidator.class.getSimpleName())) { - validator = new SearchValidator(); - } - return validator; - } - - private static Properties getLdaptiveProperties(String ldapSystemName) { - Properties _ldaptiveProperties = new Properties(); - String ldapPropertyPrefix = "ldap." + ldapSystemName + "."; - - _ldaptiveProperties.setProperty("org.ldaptive.bindDn", ""); - - // load this ldaptive config file before the configs here. load from classpath - String configFileFromClasspathParam = ldapPropertyPrefix + "configFileFromClasspath"; - String configFileFromClasspathValue = GrouperLoaderConfig.retrieveConfig().propertyValueString(configFileFromClasspathParam); - if (!StringUtils.isBlank(configFileFromClasspathValue)) { - URL url = GrouperUtil.computeUrl(configFileFromClasspathValue, false); - try { - _ldaptiveProperties.load(url.openStream()); - } catch (IOException ioe) { - throw new RuntimeException("Error processing classpath file: " + configFileFromClasspathValue, ioe); - } - } - - for (String propName : GrouperLoaderConfig.retrieveConfig().propertyNames()) { - if ( propName.startsWith(ldapPropertyPrefix) ) { - String propValue = GrouperLoaderConfig.retrieveConfig().propertyValueString(propName, ""); - - // Get the part of the property after ldapPropertyPrefix 'ldap.person.' - String propNameTail = propName.substring(ldapPropertyPrefix.length()); - - if (propValue == null) { - propValue = ""; - } - - // GRP-4484: ldaptive upgrade now uses durations - if (propNameTail.equalsIgnoreCase("timeout") || propNameTail.equalsIgnoreCase("timeLimit")) { - if (!StringUtils.isBlank(propValue)) { - try { - propValue = "PT" + (GrouperUtil.longValue(propValue)/1000) + "S"; - } catch (Throwable t) { - // if its not a number, then forget it - LOG.debug("Error parsing: " + propValue, t); - } - } - } - _ldaptiveProperties.put("org.ldaptive." + propNameTail, propValue); - - if (propNameTail.equalsIgnoreCase("url")) { - LOG.info("Setting org.ldaptive.ldapUrl"); - _ldaptiveProperties.put("org.ldaptive.ldapUrl", propValue); - } - // tls (vtldap) ==> useStartTls - if (propNameTail.equalsIgnoreCase("tls")) { - LOG.info("Setting org.ldaptive.useStartTLS"); - _ldaptiveProperties.put("org.ldaptive.useStartTLS", propValue); - } - // user (vtldap) ==> bindDn - if (propNameTail.equalsIgnoreCase("user")) { - LOG.info("Setting org.ldaptive.bindDn"); - _ldaptiveProperties.put("org.ldaptive.bindDn", propValue); - } - // pass (vtldap) ==> bindCredential - if (propNameTail.equalsIgnoreCase("pass")) { - LOG.info("Setting org.ldaptive.bindCredential"); - _ldaptiveProperties.put("org.ldaptive.bindCredential", propValue); - } - // countLimit (vtldap) ==> sizeLimit - if (propNameTail.equalsIgnoreCase("countLimit")) { - LOG.info("Setting org.ldaptive.sizeLimit"); - _ldaptiveProperties.put("org.ldaptive.sizeLimit", propValue); - } - // timeout (vtldap) ==> connectTimeout - if (propNameTail.equalsIgnoreCase("timeout")) { - LOG.info("Setting org.ldaptive.connectTimeout"); - _ldaptiveProperties.put("org.ldaptive.connectTimeout", propValue); - } - } - } - - // Go through the properties that can be encrypted and decrypt them if they're Morph files - for (String encryptablePropertyKey : ENCRYPTABLE_LDAPTIVE_PROPERTIES) { - String value = _ldaptiveProperties.getProperty(encryptablePropertyKey); - value = Morph.decryptIfFile(value); - _ldaptiveProperties.put(encryptablePropertyKey, value); - } - return _ldaptiveProperties; - } - - - /** - * call this to send a callback for the ldap session object. - * @param ldapServerId is the config id from the grouper-loader.properties - * @param ldapHandler is the logic of the ldap calls - * @return the result of the handler - */ - private static Object callbackLdapSession( - String ldapServerId, LdapHandler ldapHandler) { - - Object ret = null; - PooledConnectionFactory blockingLdapPool = null; - Connection ldap = null; - try { - - blockingLdapPool = blockingLdapPool(ldapServerId); - - if (LOG.isDebugEnabled()) { - LOG.debug("pre-checkout: ldap id: " + ldapServerId + ", pool active: " + blockingLdapPool.getConnectionPool().activeCount() + ", available: " + blockingLdapPool.getConnectionPool().availableCount()); - } - - ldap = blockingLdapPool.getConnection(); - - if (LOG.isDebugEnabled()) { - LOG.debug("post-checkout: ldap id: " + ldapServerId + ", pool active: " + blockingLdapPool.getConnectionPool().activeCount() + ", available: " + blockingLdapPool.getConnectionPool().availableCount()); - } - - LdapHandlerBean ldapHandlerBean = new LdapHandlerBean(); - - ldapHandlerBean.setLdap(ldap); - - ret = ldapHandler.callback(ldapHandlerBean); - - } catch (RuntimeException re) { - GrouperUtil.injectInException(re, "Problem with ldap conection: " + ldapServerId); - throw re; - } catch (Exception e) { - throw new RuntimeException("Problem with ldap conection: " + ldapServerId, e); - } finally { - if (ldap != null) { - try { - ldap.close(); - } catch (Exception e) { - // ignore - } - } - } - return ret; - - } - - /** - * @see edu.internet2.middleware.grouper.ldap.LdapSession#list(java.lang.Class, java.lang.String, java.lang.String, edu.internet2.middleware.grouper.ldap.LdapSearchScope, java.lang.String, java.lang.String) - */ - @SuppressWarnings("unchecked") - public List list(final Class returnType, final String ldapServerId, - final String searchDn, final LdapSearchScope ldapSearchScope, final String filter, final String attributeName) { - - try { - - return (List)callbackLdapSession(ldapServerId, new LdapHandler() { - - public Object callback(LdapHandlerBean ldapHandlerBean) throws LdapException { - - Connection ldap = ldapHandlerBean.getLdap(); - - SearchResult searchResult = processSearchRequest(ldapServerId, ldap, searchDn, ldapSearchScope, filter, new String[] { attributeName }, null); - - List result = new ArrayList(); - for (LdapEntry entry : searchResult.getEntries()) { - LdapAttribute attribute = entry.getAttribute(attributeName); - - if (attribute == null && StringUtils.equals("dn", attributeName)) { - String nameInNamespace = entry.getDn(); - Object attributeValue = GrouperUtil.typeCast(nameInNamespace, returnType); - result.add((R)attributeValue); - } else { - - if (attribute != null) { - for (Object attributeValue : attribute.getStringValues()) { - - attributeValue = GrouperUtil.typeCast(attributeValue, returnType); - if (attributeValue != null) { - result.add((R)attributeValue); - } - } - } - } - } - - if (LOG.isDebugEnabled()) { - LOG.debug("Found " + result.size() + " results for serverId: " + ldapServerId + ", searchDn: " + searchDn - + ", filter: '" + filter + "', returning attribute: " - + attributeName + ", some results: " + GrouperUtil.toStringForLog(result, 100) ); - } - - return result; - } - }); - } catch (RuntimeException re) { - GrouperUtil.injectInException(re, "Error querying ldap server id: " + ldapServerId + ", searchDn: " + searchDn - + ", filter: '" + filter + "', returning attribute: " + attributeName); - throw re; - } - - } - - /** - * logger - */ - private static final Log LOG = GrouperUtil.getLog(LdaptiveSessionImpl.class); - - /** - * @see edu.internet2.middleware.grouper.ldap.LdapSession#listInObjects(java.lang.Class, java.lang.String, java.lang.String, edu.internet2.middleware.grouper.ldap.LdapSearchScope, java.lang.String, java.lang.String) - */ - @SuppressWarnings("unchecked") - public Map> listInObjects(final Class returnType, final String ldapServerId, - final String searchDn, final LdapSearchScope ldapSearchScope, final String filter, final String attributeName) { - - try { - - return (Map>)callbackLdapSession(ldapServerId, new LdapHandler() { - - public Object callback(LdapHandlerBean ldapHandlerBean) throws LdapException { - - Connection ldap = ldapHandlerBean.getLdap(); - - SearchResult searchResult = processSearchRequest(ldapServerId, ldap, searchDn, ldapSearchScope, filter, new String[] { attributeName }, null); - - Map> result = new HashMap>(); - int subObjectCount = 0; - for (LdapEntry entry : searchResult.getEntries()) { - - List valueResults = new ArrayList(); - String nameInNamespace = entry.getDn(); - - result.put(nameInNamespace, valueResults); - - LdapAttribute attribute = entry.getAttribute(attributeName); - - if (attribute != null) { - for (Object attributeValue : attribute.getStringValues()) { - - attributeValue = GrouperUtil.typeCast(attributeValue, returnType); - if (attributeValue != null) { - subObjectCount++; - valueResults.add((R)attributeValue); - } - } - } - } - - if (LOG.isDebugEnabled()) { - LOG.debug("Found " + result.size() + " results, (" + subObjectCount + " sub-results) for serverId: " + ldapServerId + ", searchDn: " + searchDn - + ", filter: '" + filter + "', returning attribute: " - + attributeName + ", some results: " + GrouperUtil.toStringForLog(result, 100) ); - } - - return result; - } - }); - } catch (RuntimeException re) { - GrouperUtil.injectInException(re, "Error querying ldap server id: " + ldapServerId + ", searchDn: " + searchDn - + ", filter: '" + filter + "', returning attribute: " + attributeName); - throw re; - } - - } - - /** - * @see edu.internet2.middleware.grouper.ldap.LdapSession#list(java.lang.String, java.lang.String, edu.internet2.middleware.grouper.ldap.LdapSearchScope, java.lang.String, java.lang.String[], java.lang.Long) - */ - @SuppressWarnings("unchecked") - public List list(final String ldapServerId, final String searchDn, - final LdapSearchScope ldapSearchScope, final String filter, final String[] attributeNames, final Long sizeLimit) { - - try { - - return (List)callbackLdapSession(ldapServerId, new LdapHandler() { - - public Object callback(LdapHandlerBean ldapHandlerBean) throws LdapException { - - Connection ldap = ldapHandlerBean.getLdap(); - - SearchResult searchResults = processSearchRequest(ldapServerId, ldap, searchDn, ldapSearchScope, filter, attributeNames, sizeLimit); - - List results = getLdapEntriesFromSearchResult(searchResults, attributeNames); - - return results; - } - }); - } catch (RuntimeException re) { - GrouperUtil.injectInException(re, "Error querying ldap server id: " + ldapServerId + ", searchDn: " + searchDn - + ", filter: '" + filter + "', returning attributes: " + StringUtils.join(attributeNames, ", ")); - throw re; - } - } - - @SuppressWarnings("unchecked") - @Override - public List read(String ldapServerId, String searchDn, List dnList, String[] attributeNames) { - try { - return (List)callbackLdapSession(ldapServerId, new LdapHandler() { - - public Object callback(LdapHandlerBean ldapHandlerBean) throws LdapException { - - Connection ldap = ldapHandlerBean.getLdap(); - - List results = new ArrayList(); - - LdapConfiguration config = LdapConfiguration.getConfig(ldapServerId); - int batchSize = config.getQueryBatchSize(); - - if (StringUtils.isEmpty(config.getDnAttributeForSearches()) && !hasWarnedAboutMissingDnAttributeForSearches) { - LOG.warn("Performance impact due to missing config: ldap." + ldapServerId + ".dnAttributeForSearches"); - hasWarnedAboutMissingDnAttributeForSearches = true; - } - - if (!StringUtils.isEmpty(config.getDnAttributeForSearches()) && batchSize > 1) { - int numberOfBatches = GrouperUtil.batchNumberOfBatches(GrouperUtil.length(dnList), batchSize); - for (int i = 0; i < numberOfBatches; i++) { - List currentBatch = GrouperUtil.batchList(dnList, batchSize, i); - StringBuilder builder = new StringBuilder(); - for (String dn : currentBatch) { - builder.append("(" + config.getDnAttributeForSearches() + "=" + SearchFilter.encodeValue(dn) + ")"); - } - - String filter = "(|" + builder.toString() + ")"; - SearchResult searchResults = processSearchRequest(ldapServerId, ldap, searchDn, LdapSearchScope.SUBTREE_SCOPE, filter, attributeNames, null); - results.addAll(getLdapEntriesFromSearchResult(searchResults, attributeNames)); - } - } else { - for (String dn : dnList) { - SearchResult searchResults = processSearchRequest(ldapServerId, ldap, dn, LdapSearchScope.OBJECT_SCOPE, "(objectclass=*)", attributeNames, null); - results.addAll(getLdapEntriesFromSearchResult(searchResults, attributeNames)); - } - } - - return results; - } - }); - } catch (RuntimeException re) { - GrouperUtil.injectInException(re, "Error querying ldap server id: " + ldapServerId + ", dnList size: " + dnList.size() - + ", returning attributes: " + StringUtils.join(attributeNames, ", ")); - throw re; - } - } - - /** - * @see edu.internet2.middleware.grouper.ldap.LdapSession#authenticate(java.lang.String, java.lang.String, java.lang.String) - */ - public void authenticate(final String ldapServerId, final String userDn, final String password) { - - callbackLdapSession(ldapServerId, new LdapHandler() { - - public Object callback(LdapHandlerBean ldapHandlerBean) throws LdapException { - - Connection ldap = ldapHandlerBean.getLdap(); - - ConnectionConfig connectionConfig = ConnectionConfig.newConnectionConfig(ldap.getConnectionConfig()); - connectionConfig.setConnectionInitializer(null); - Connection ldap2 = DefaultConnectionFactory.getConnection(connectionConfig); - - try { - ldap2.open(); - BindOperation bind = new BindOperation(ldap2); - bind.execute(new BindRequest(userDn, new Credential(password))); - } finally { - try { - ldap2.close(); - } catch (Exception e) { - // ignore - } - } - - return null; - } - }); - - } - - private SearchScope translateScope(LdapSearchScope jndiScope) { - if (jndiScope == null) { - return null; - } - - SearchScope ldaptiveScope = null; - - if (jndiScope == LdapSearchScope.OBJECT_SCOPE) { - ldaptiveScope = SearchScope.OBJECT; - } else if (jndiScope == LdapSearchScope.ONELEVEL_SCOPE) { - ldaptiveScope = SearchScope.ONELEVEL; - } else if (jndiScope == LdapSearchScope.SUBTREE_SCOPE) { - ldaptiveScope = SearchScope.SUBTREE; - } else { - throw new RuntimeException("Unexpected scope " + jndiScope); - } - - return ldaptiveScope; - } - - private AttributeModificationType translateModificationType(LdapModificationType modificationType) { - if (modificationType == null) { - return null; - } - - AttributeModificationType ldaptiveModificationType = null; - - if (modificationType == LdapModificationType.ADD_ATTRIBUTE) { - ldaptiveModificationType = AttributeModificationType.ADD; - } else if (modificationType == LdapModificationType.REMOVE_ATTRIBUTE) { - ldaptiveModificationType = AttributeModificationType.REMOVE; - } else if (modificationType == LdapModificationType.REPLACE_ATTRIBUTE) { - ldaptiveModificationType = AttributeModificationType.REPLACE; - } else { - throw new RuntimeException("Unexpected modification type " + modificationType); - } - - return ldaptiveModificationType; - } - - private SearchResult processSearchRequest(String ldapServerId, Connection ldap, String searchDn, LdapSearchScope ldapSearchScope, String filter, String[] attributeNames, Long sizeLimit) throws LdapException { - - SearchRequest searchRequest = new SearchRequest(); - - if (filter != null) { - filter = filter.trim(); - if (filter.startsWith("${") && filter.endsWith("}")) { - - if (this.debug) { - this.debugLog.append("Ldaptive filterJexl '").append(filter).append("'\n"); - } - filter = StringUtils.replace(filter, "$newline$", "\n"); - Map variableMap = new HashMap(); - variableMap.put("grouperUtil", new GrouperUtil()); - filter = (String)GrouperUtil.substituteExpressionLanguageScript(filter, variableMap, true, false, false); - } - } - - searchRequest.setSearchFilter(new SearchFilter(filter)); - searchRequest.setReturnAttributes(attributeNames); - - if (searchEntryHandlers.get(ldapServerId).size() > 0) { - SearchEntryHandler[] handlers = new SearchEntryHandler[searchEntryHandlers.get(ldapServerId).size()]; - int count = 0; - for (Class handlerClass : searchEntryHandlers.get(ldapServerId)) { - handlers[count] = GrouperUtil.newInstance(handlerClass); - count++; - } - - searchRequest.setSearchEntryHandlers(handlers); - } - - SearchRequestPropertySource srSource = new SearchRequestPropertySource(searchRequest, propertiesMap.get(ldapServerId)); - srSource.initialize(); - - // add this after the properties get initialized so that this would override if needed - // note that the searchDn here is relative - if (StringUtils.isNotBlank(searchDn)) { - searchRequest.setBaseDn(searchDn); - } - - if (sizeLimit != null) { - searchRequest.setSizeLimit(sizeLimit); - } - - if (ldapSearchScope != null) { - searchRequest.setSearchScope(translateScope(ldapSearchScope)); - } - - if ("follow".equals(GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".referral"))) { - searchRequest.setReferralHandler(new SearchReferralHandler()); - } - - Response response = null; - SearchResult searchResults; - - Integer pageSize = LdapConfiguration.getConfig(ldapServerId).getPageSize(); - if (pageSize != null) { - if (pageSize < 0) { - pageSize = null; - } - } else if (LdapConfiguration.getConfig(ldapServerId).isActiveDirectory()) { - pageSize = getDefaultActiveDirectoryPageSize(ldapServerId, ldap); - } - - if (this.debug) { - this.debugLog.append("Ldaptive searchRequest (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(searchRequest.toString(), 2000)).append("\n"); - } - if (pageSize == null) { - SearchOperation search = new SearchOperation(ldap); - response = search.execute(searchRequest); - } else { - PagedResultsClient client = new PagedResultsClient(ldap, pageSize); - response = client.executeToCompletion(searchRequest); - } - if (this.debug) { - this.debugLog.append("Ldaptive searchResponse (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(response.toString(), 2000)).append("\n"); - } - searchResults = response.getResult(); - if (this.debug) { - this.debugLog.append("Ldaptive searchResults (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(searchResults.toString(), 2000)).append("\n"); - } - return searchResults; - } - - private synchronized Integer getDefaultActiveDirectoryPageSize(String ldapServerId, Connection ldap) { - Integer pageSize = 1000; - - try { - LdapEntry rootLdapEntry; - - { - SearchRequest searchRequest = new SearchRequest(); - searchRequest.setSearchFilter(new SearchFilter("(objectClass=*)")); - searchRequest.setReturnAttributes("configurationNamingContext"); - searchRequest.setBaseDn(""); - searchRequest.setSearchScope(SearchScope.OBJECT); - - if ("follow".equals(GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".referral"))) { - searchRequest.setReferralHandler(new SearchReferralHandler()); - } - - SearchOperation search = new SearchOperation(ldap); - Response response = search.execute(searchRequest); - SearchResult searchResult = response.getResult(); - rootLdapEntry = searchResult.getEntry(); - } - if (rootLdapEntry != null && rootLdapEntry.getAttribute("configurationNamingContext") != null && !GrouperUtil.isEmpty(rootLdapEntry.getAttribute("configurationNamingContext").getStringValue())) { - String configurationDn = rootLdapEntry.getAttribute("configurationNamingContext").getStringValue(); - - SearchRequest searchRequest = new SearchRequest(); - searchRequest.setSearchFilter(new SearchFilter("(&(objectClass=queryPolicy)(cn=Default Query Policy))")); - searchRequest.setReturnAttributes("lDAPAdminLimits"); - searchRequest.setBaseDn(configurationDn); - searchRequest.setSearchScope(SearchScope.SUBTREE); - - if ("follow".equals(GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".referral"))) { - searchRequest.setReferralHandler(new SearchReferralHandler()); - } - - SearchOperation search = new SearchOperation(ldap); - Response response = search.execute(searchRequest); - SearchResult searchResult = response.getResult(); - LdapEntry queryPolicyLdapEntry = searchResult.getEntry(); - if (queryPolicyLdapEntry != null && queryPolicyLdapEntry.getAttribute("lDAPAdminLimits") != null) { - for (String adminLimit : GrouperUtil.nonNull(queryPolicyLdapEntry.getAttribute("lDAPAdminLimits").getStringValues())) { - if (adminLimit != null && adminLimit.startsWith("MaxPageSize=")) { - String pageSizeString = adminLimit.substring("MaxPageSize=".length()); - pageSize = Integer.parseInt(pageSizeString); - LOG.warn("Using pagedResultsSize from " + queryPolicyLdapEntry.getDn()); - break; - } - } - } - - } - } catch (Exception e) { - LOG.error("Exception trying to determine default Active Directory page size", e); - } - - LOG.warn("pagedResultsSize is not set for '" + ldapServerId + "' even though it is usually required with Active Directory. Set to -1 to force no paging. Defaulting to " + pageSize + "."); - - LdapConfiguration.getConfig(ldapServerId).setPageSize(pageSize); - - return pageSize; - } - - private List getLdapEntriesFromSearchResult(SearchResult searchResults, String[] attributeNames) { - - List results = new ArrayList(); - - for (LdapEntry searchResult : searchResults.getEntries()) { - - String nameInNamespace = searchResult.getDn(); - - edu.internet2.middleware.grouper.ldap.LdapEntry entry = new edu.internet2.middleware.grouper.ldap.LdapEntry(nameInNamespace); - for (String attributeName : attributeNames) { - edu.internet2.middleware.grouper.ldap.LdapAttribute attribute = new edu.internet2.middleware.grouper.ldap.LdapAttribute(attributeName); - - LdapAttribute sourceAttribute = searchResult.getAttribute(attributeName); - if (sourceAttribute != null) { - if (sourceAttribute.isBinary()) { - attribute.setBinaryValues(sourceAttribute.getBinaryValues()); - } else { - attribute.setStringValues(sourceAttribute.getStringValues()); - } - } - - entry.addAttribute(attribute); - } - - results.add(entry); - } - - return results; - } - - @Override - public void delete(final String ldapServerId, final String dn) { - - try { - - if (GrouperUtil.isEmpty(dn)) { - throw new RuntimeException("No dn!"); - } - - callbackLdapSession(ldapServerId, new LdapHandler() { - - public Object callback(LdapHandlerBean ldapHandlerBean) throws LdapException { - - Connection ldap = ldapHandlerBean.getLdap(); - - DeleteOperation delete = new DeleteOperation(ldap); - DeleteRequest deleteRequest = new DeleteRequest(dn); - - if ("follow".equals(GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".referral"))) { - deleteRequest.setReferralHandler(new DeleteReferralHandler()); - } - if (debug) { - debugLog.append("Ldaptive deleteRequest (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(deleteRequest.toString(), 2000)).append("\n"); - } - - try { - Response response = delete.execute(deleteRequest); - if (debug) { - debugLog.append("Ldaptive deleteResponse (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(response.toString(), 2000)).append("\n"); - } - if (response.getResultCode() == ResultCode.SUCCESS) { - return null; - } else { - throw new RuntimeException("Received result code: " + response.getResultCode()); - } - } catch (LdapException e) { - - - // note that this only happens if an intermediate context does not exist - if (e.getResultCode() == ResultCode.NO_SUCH_OBJECT) { - if (debug) { - debugLog.append("Ldaptive deleteResultCode (").append(ldapServerId).append("): NO_SUCH_OBJECT\n"); - } - return null; - } - - if (debug) { - debugLog.append("Ldaptive delete error (").append(ldapServerId).append("): ").append(GrouperUtil.getFullStackTrace(e)).append("\n"); - } - - // TODO should we re-query just to be sure? - throw e; - } - } - }); - } catch (RuntimeException re) { - GrouperUtil.injectInException(re, "Error deleting entry server id: " + ldapServerId + ", dn: " + dn); - throw re; - } - } - - @Override - public boolean create(final String ldapServerId, final edu.internet2.middleware.grouper.ldap.LdapEntry ldapEntry) { - - // if create failed because object is there, then do an update with the attributes that were given - // some attributes given may have no values and therefore clear those attributes - // true if created, false if updated - - try { - if (GrouperUtil.isEmpty(ldapEntry.getDn())) { - throw new RuntimeException("No dn!"); - } - - return (Boolean)callbackLdapSession(ldapServerId, new LdapHandler() { - - public Object callback(LdapHandlerBean ldapHandlerBean) throws LdapException { - - Connection ldap = ldapHandlerBean.getLdap(); - - List ldaptiveAttributes = new ArrayList(); // if doing create - List ldaptiveModifications = new ArrayList(); // if doing modify - - for (edu.internet2.middleware.grouper.ldap.LdapAttribute grouperLdapAttribute : ldapEntry.getAttributes()) { - LdapAttribute ldaptiveAttribute = new LdapAttribute(grouperLdapAttribute.getName()); - if (grouperLdapAttribute.getStringValues().size() > 0) { - ldaptiveAttribute.addStringValues(grouperLdapAttribute.getStringValues()); - } else if (grouperLdapAttribute.getBinaryValues().size() > 0) { - ldaptiveAttribute.addBinaryValues(grouperLdapAttribute.getBinaryValues()); - } - - if (ldaptiveAttribute.size() > 0) { - ldaptiveAttributes.add(ldaptiveAttribute); - } - - ldaptiveModifications.add(new AttributeModification(AttributeModificationType.REPLACE, ldaptiveAttribute)); - } - - AddOperation add = new AddOperation(ldap); - AddRequest addRequest = new AddRequest(); - addRequest.setDn(ldapEntry.getDn()); - addRequest.setLdapAttributes(ldaptiveAttributes); - - if ("follow".equals(GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".referral"))) { - addRequest.setReferralHandler(new AddReferralHandler()); - } - if (debug) { - debugLog.append("Ldaptive addRequest (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(addRequest.toString(), 2000)).append("\n"); - } - - try { - Response response = add.execute(addRequest); - if (debug) { - debugLog.append("Ldaptive addResponse (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(response.toString(), 2000)).append("\n"); - } - if (response.getResultCode() == ResultCode.SUCCESS) { - return true; - } else { - throw new RuntimeException("Received result code: " + (response == null ? null : response.getResultCode())); - } - } catch (LdapException e) { - - // update attributes instead - if (e.getResultCode() == ResultCode.ENTRY_ALREADY_EXISTS) { - if (debug) { - debugLog.append("Ldaptive addResponse (").append(ldapServerId).append("): ENTRY_ALREADY_EXISTS\n"); - } - ModifyOperation modify = new ModifyOperation(ldap); - ModifyRequest modifyRequest = new ModifyRequest(ldapEntry.getDn(), ldaptiveModifications.toArray(new AttributeModification[] { })); - - if ("follow".equals(GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".referral"))) { - modifyRequest.setReferralHandler(new ModifyReferralHandler()); - } - if (debug) { - debugLog.append("Ldaptive addModifyRequest (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(modifyRequest.toString(), 2000)).append("\n"); - } - - Response response = modify.execute(modifyRequest); - if (debug) { - debugLog.append("Ldaptive addModifyResponse (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(response.toString(), 2000)).append("\n"); - } - if (response.getResultCode() == ResultCode.SUCCESS) { - return false; - } else { - throw new RuntimeException("Received result code: " + response.getResultCode()); - } - } - if (debug) { - debugLog.append("Ldaptive add error (").append(ldapServerId).append("): ").append(GrouperUtil.getFullStackTrace(e)).append("\n"); - } - - throw e; - } - } - }); - } catch (RuntimeException re) { - GrouperUtil.injectInException(re, "Error creating entry server id: " + ldapServerId + ", dn: " + ldapEntry.getDn()); - throw re; - } - } - - @Override - public boolean move(final String ldapServerId, final String oldDn, final String newDn) { - // return true if moved - // return false if newDn exists and oldDn doesn't - try { - - if (GrouperUtil.isEmpty(oldDn)) { - throw new RuntimeException("No oldDn!"); - } - - if (GrouperUtil.isEmpty(newDn)) { - throw new RuntimeException("No newDn!"); - } - - return (Boolean)callbackLdapSession(ldapServerId, new LdapHandler() { - - public Object callback(LdapHandlerBean ldapHandlerBean) throws LdapException { - - Connection ldap = ldapHandlerBean.getLdap(); - - ModifyDnOperation modifyDn = new ModifyDnOperation(ldap); - ModifyDnRequest modifyDnRequest = new ModifyDnRequest(); - modifyDnRequest.setDeleteOldRDn(true); - modifyDnRequest.setDn(oldDn); - modifyDnRequest.setNewDn(newDn); - - if ("follow".equals(GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".referral"))) { - modifyDnRequest.setReferralHandler(new ModifyDnReferralHandler()); - } - - if (debug) { - debugLog.append("Ldaptive moveRequest (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(modifyDnRequest.toString(), 2000)).append("\n"); - } - try { - Response response = modifyDn.execute(modifyDnRequest); - if (debug) { - debugLog.append("Ldaptive moveResponse (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(response.toString(), 2000)).append("\n"); - } - if (response.getResultCode() == ResultCode.SUCCESS) { - return true; - } else { - throw new RuntimeException("Received result code: " + response.getResultCode()); - } - } catch (LdapException e) { - - if (e.getResultCode() == ResultCode.NO_SUCH_OBJECT) { - - if (debug) { - debugLog.append("Ldaptive moveResponse (").append(ldapServerId).append("): NO_SUCH_OBJECT\n"); - } - // old entry doesn't exist. if the new one does, then let's assume it was already renamed and return false - // note that this exception could also happen if the oldDn exists but the newDn is an invalid location - in that case we should still end up throwing the original exception below - - try { - processSearchRequest(ldapServerId, ldap, newDn, LdapSearchScope.OBJECT_SCOPE, "(objectclass=*)", new String[] { "objectclass" }, null); - return false; - } catch (LdapException e2) { - if (e2.getResultCode() == ResultCode.NO_SUCH_OBJECT) { - // throw original exception - throw e; - } - - // something else went wrong so throw this - throw e2; - } - } - if (debug) { - debugLog.append("Ldaptive move error (").append(ldapServerId).append("): ").append(GrouperUtil.getFullStackTrace(e)).append("\n"); - } - throw e; - } - } - }); - } catch (RuntimeException re) { - GrouperUtil.injectInException(re, "Error moving entry server id: " + ldapServerId + ", oldDn: " + oldDn + ", newDn: " + newDn); - throw re; - } - } - - @Override - public void internal_modifyHelper(final String ldapServerId, String dn, final List ldapModificationItems) { - - if (ldapModificationItems.size() == 0) { - return; - } - - try { - - if (GrouperUtil.isEmpty(dn)) { - throw new RuntimeException("No dn!"); - } - - callbackLdapSession(ldapServerId, new LdapHandler() { - - public Object callback(LdapHandlerBean ldapHandlerBean) throws LdapException { - - Connection ldap = ldapHandlerBean.getLdap(); - - List ldaptiveModifications = new ArrayList(); - - for (LdapModificationItem ldapModificationItem : ldapModificationItems) { - LdapAttribute ldaptiveAttribute = new LdapAttribute(ldapModificationItem.getAttribute().getName()); - if (ldapModificationItem.getAttribute().getStringValues().size() > 0) { - ldaptiveAttribute.addStringValues(ldapModificationItem.getAttribute().getStringValues()); - } else if (ldapModificationItem.getAttribute().getBinaryValues().size() > 0) { - ldaptiveAttribute.addBinaryValues(ldapModificationItem.getAttribute().getBinaryValues()); - } - - ldaptiveModifications.add(new AttributeModification(translateModificationType(ldapModificationItem.getLdapModificationType()), ldaptiveAttribute)); - } - - ModifyOperation modify = new ModifyOperation(ldap); - ModifyRequest modifyRequest = new ModifyRequest(dn, ldaptiveModifications.toArray(new AttributeModification[] { })); - - if ("follow".equals(GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".referral"))) { - modifyRequest.setReferralHandler(new ModifyReferralHandler()); - } - - if (debug) { - debugLog.append("Ldaptive modifyRequest (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(modifyRequest.toString(), 2000)).append("\n"); - } - - Response response = modify.execute(modifyRequest); - if (debug) { - debugLog.append("Ldaptive modifyResponse (").append(ldapServerId).append("): ").append(StringUtils.abbreviate(response.toString(), 2000)).append("\n"); - } - if (response.getResultCode() == ResultCode.SUCCESS) { - return null; - } else { - throw new RuntimeException("Received result code: " + response.getResultCode()); - } - } - }); - } catch (RuntimeException re) { - if (debug) { - debugLog.append("Ldaptive modify error (").append(ldapServerId).append("): ").append(GrouperUtil.getFullStackTrace(re)).append("\n"); - } - GrouperUtil.injectInException(re, "Error modifying entry server id: " + ldapServerId + ", dn: " + dn); - throw re; - } - } - - @Override - public boolean testConnection(final String ldapServerId) { - Validator validator = retrieveValidator(ldapServerId); - boolean valid = false; - if (validator != null) { - valid = (Boolean)callbackLdapSession(ldapServerId, new LdapHandler() { - - @Override - public Object callback(LdapHandlerBean ldapHandlerBean) - throws Exception { - return validator.validate(ldapHandlerBean.getLdap()); - } - }); - } - // if not valid, maybe this will throw a useful exception - if (validator == null || !valid) { - String user = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".user"); - String pass = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapServerId + ".pass"); - pass = Morph.decryptIfFile(pass); - authenticate(ldapServerId, user, - pass); - } - return valid; - } - - public void refreshConnectionsIfNeeded(final String ldapServerId) { - synchronized (LdaptiveSessionImpl.class) { - - Iterator poolsNeedingCleanupIter = poolsNeedingCleanup.iterator(); - while (poolsNeedingCleanupIter.hasNext()) { - PooledConnectionFactory pool = poolsNeedingCleanupIter.next(); - if (pool.getConnectionPool().activeCount() == 0) { - pool.getConnectionPool().close(); - poolsNeedingCleanupIter.remove(); - LOG.warn("Closed old LDAP pool after confirming not in use."); - } else { - LOG.warn("Unable to close old LDAP pool since it is being used. Will check again later."); - } - } - - if (poolMap.containsKey(ldapServerId) && propertiesMap.containsKey(ldapServerId)) { - if (!propertiesMap.get(ldapServerId).equals(getLdaptiveProperties(ldapServerId))) { - PooledConnectionFactory pool = poolMap.remove(ldapServerId); - poolsNeedingCleanup.add(pool); - LdapConfiguration.removeConfig(ldapServerId); - } - } - } - } -} diff --git a/container_files/grouperWebapp/WEB-INF/libWs/jersey-container-servlet-2.36.jar b/container_files/grouperWebapp/WEB-INF/libWs/jersey-container-servlet-2.36.jar deleted file mode 100644 index 8e82349bcf993a022967dd77b0eccdd6febc37d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32381 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 P__qWL0ut){^xyvjXds|h