diff --git a/grouper/conf/grouper-loader.base.properties b/grouper/conf/grouper-loader.base.properties index 966b2cf73ed4..883f6e58d1eb 100644 --- a/grouper/conf/grouper-loader.base.properties +++ b/grouper/conf/grouper-loader.base.properties @@ -2950,6 +2950,10 @@ grouper.provisioning.removeSyncLogRowsAfterDays = 7 # {valueType: "boolean", order: 3500, indent: 1, defaultValue: "true", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud}"} # provisioner.genericProvisioner.deleteMemberships = +# Delete memberships filter by object type +# {valueType: "string", order: 3550, indent: 2, defaultValue: "", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud && deleteMemberships}", formElement: "dropdown", optionValues: ["", "user", "group", "entity"]} +provisioner.genericProvisioner.deleteMembershipsObjectTypeFilter = + # Delete memberships if not exist in grouper # {valueType: "boolean", order: 4500, indent: 2, defaultValue: "false", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud && deleteMemberships}"} # provisioner.genericProvisioner.deleteMembershipsIfNotExistInGrouper = diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningBehavior.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningBehavior.java index f5d073ddb28c..46dce3ca997b 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningBehavior.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningBehavior.java @@ -1237,7 +1237,17 @@ public boolean isDeleteMembership(ProvisioningMembershipWrapper provisioningMemb if (provisioningMembershipWrapper == null) { return this.isDeleteMembershipsIfNotExistInGrouper(); } - + // Apply object type filter + String objectTypeFilter = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getDeleteMembershipsObjectTypeFilter(); + if (!StringUtils.isBlank(objectTypeFilter)) { + ProvisioningEntity provisioningEntity = provisioningMembershipWrapper.getProvisioningEntity(); + if (provisioningEntity != null) { + String entityType = provisioningEntity.getEntityType(); + if (!objectTypeFilter.equals(entityType)) { + return false; + } + } + } if ((this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().isOperateOnGrouperGroups() && !this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isDeleteGroupsIfUnmarkedProvisionable()) || (this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().isOperateOnGrouperMemberships() && !this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isDeleteMembershipsIfGroupUnmarkedProvisionable())) { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfiguration.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfiguration.java index 1385aa2ce10c..f4cb1ce2f28f 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfiguration.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfiguration.java @@ -1987,7 +1987,10 @@ public void setSelectMemberships(boolean selectMemberships) { * if memberships should be deleted in target */ private boolean deleteMemberships = true; - + /** + * delete memberships object type filter + */ + private String deleteMembershipsObjectTypeFilter; /** * */ diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationValidation.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationValidation.java index 6060591cb17d..02f3dd763ce5 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationValidation.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationValidation.java @@ -798,12 +798,22 @@ public void validateMembershipDeleteHasDeleteType() { if (deleteMembershipsIfGrouperCreated) { deleteTypes++; } - + if (deleteTypes != 1) { this.addErrorMessage(new ProvisioningValidationIssue() .assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.oneMembershipDeleteType")) .assignJqueryHandle("deleteMemberships")); } + // Add validation for object type filter + String objectTypeFilter = (String) suffixToConfigValue.get("deleteMembershipsObjectTypeFilter"); + if (!StringUtils.isBlank(objectTypeFilter)) { + Set validObjectTypes = GrouperUtil.toSet("user", "group", "entity"); + if (!validObjectTypes.contains(objectTypeFilter)) { + this.addErrorMessage(new ProvisioningValidationIssue() + .assignMessage("Invalid object type filter: " + objectTypeFilter) + .assignJqueryHandle("deleteMembershipsObjectTypeFilter")); + } + } } } @@ -1738,4 +1748,4 @@ public Collection validateEntityAttributeNamesForbidden() { } } - \ No newline at end of file +