[SYNCOPE-1300] ignoreCase checks implemented both during Pull and Propagation
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/1a3a05e2 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/1a3a05e2 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/1a3a05e2 Branch: refs/heads/master Commit: 1a3a05e2341ab5b1b61f293882d4038c7050259c Parents: a482f0b Author: Francesco Chicchiriccò <[email protected]> Authored: Fri Apr 20 16:24:48 2018 +0200 Committer: Francesco Chicchiriccò <[email protected]> Committed: Fri Apr 20 16:24:48 2018 +0200 ---------------------------------------------------------------------- .../resources/ObjectTypeTogglePanel.java | 5 +- .../resources/ProvisionWizardBuilder.java | 68 ++++++++-------- .../wizards/resources/ResourceMappingPanel.java | 10 +-- .../wizards/resources/ResourceProvision.java | 12 +++ .../ProvisionWizardBuilder$ObjectType.html | 1 + ...ProvisionWizardBuilder$ObjectType.properties | 1 + ...visionWizardBuilder$ObjectType_it.properties | 1 + ...visionWizardBuilder$ObjectType_ja.properties | 1 + ...ionWizardBuilder$ObjectType_pt_BR.properties | 1 + ...visionWizardBuilder$ObjectType_ru.properties | 1 + .../apache/syncope/common/lib/to/MappingTO.java | 2 +- .../apache/syncope/common/lib/to/OrgUnitTO.java | 10 +++ .../syncope/common/lib/to/ProvisionTO.java | 10 +++ .../syncope/core/logic/ReconciliationLogic.java | 1 + .../syncope/core/logic/ResourceLogic.java | 1 + .../core/persistence/api/dao/AnyDAO.java | 7 +- .../api/entity/resource/OrgUnit.java | 4 + .../api/entity/resource/Provision.java | 4 + .../persistence/jpa/dao/AbstractAnyDAO.java | 52 ++++++++----- .../jpa/entity/resource/JPAOrgUnit.java | 18 +++++ .../jpa/entity/resource/JPAProvision.java | 18 +++++ .../core/persistence/jpa/inner/UserTest.java | 32 +++++--- .../core/persistence/jpa/outer/UserTest.java | 4 +- .../core/provisioning/api/Connector.java | 7 +- .../provisioning/java/AsyncConnectorFacade.java | 12 ++- .../provisioning/java/ConnectorFacadeProxy.java | 3 +- .../provisioning/java/VirAttrHandlerImpl.java | 29 +++---- .../java/data/ResourceDataBinderImpl.java | 6 ++ .../job/report/ReconciliationReportlet.java | 1 + .../AbstractPropagationTaskExecutor.java | 2 + .../pushpull/AbstractPushResultHandler.java | 4 + .../pushpull/DefaultRealmPushResultHandler.java | 4 + .../pushpull/LDAPMembershipPullActions.java | 5 +- .../java/pushpull/PullJobDelegate.java | 23 +++++- .../provisioning/java/pushpull/PullUtils.java | 82 ++++++++++++++------ .../java/pushpull/SinglePullJobDelegate.java | 11 ++- .../core/logic/saml2/SAML2UserManager.java | 8 +- pom.xml | 2 +- .../concepts/externalresources.adoc | 2 + .../concepts/provisioning/pull.adoc | 4 +- 40 files changed, 338 insertions(+), 131 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java index 0f14284..d1f72ec 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java @@ -36,15 +36,16 @@ public abstract class ObjectTypeTogglePanel extends TogglePanel<Serializable> { ObjectTypeTogglePanel( final String id, - final ResourceProvision item, + final ResourceProvision resourceProvision, final LoadableDetachableModel<List<String>> anyTypes, final PageReference pageRef) { + super(id, pageRef); Form<?> form = new Form<>("objectTypeForm"); addInnerObject(form); - PropertyModel<String> typeModel = new PropertyModel<>(item, "anyType"); + PropertyModel<String> typeModel = new PropertyModel<>(resourceProvision, "anyType"); form.add(new AjaxDropDownChoicePanel<>( "type", "type", typeModel, false). http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java index 5d7c62b..40086f9 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java @@ -64,19 +64,23 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ResourceProvision> private static final long serialVersionUID = -1657800545799468278L; - ObjectType(final ResourceProvision item) { + ObjectType(final ResourceProvision resourceProvision) { super(new ResourceModel("clazz.title", StringUtils.EMPTY), - new ResourceModel("clazz.summary", StringUtils.EMPTY), new Model<>(item)); + new ResourceModel("clazz.summary", StringUtils.EMPTY), new Model<>(resourceProvision)); - final WebMarkupContainer container = new WebMarkupContainer("container"); + WebMarkupContainer container = new WebMarkupContainer("container"); container.setOutputMarkupId(true); add(container); clazz = new AjaxTextFieldPanel( - "clazz", "clazz", new PropertyModel<>(item, "objectClass")); + "clazz", "clazz", new PropertyModel<>(resourceProvision, "objectClass")); clazz.setRequired(true); clazz.setChoices(connectorRestClient.getObjectClasses(resourceTO.getConnector())); container.add(clazz); + + AjaxCheckBoxPanel ignoreCaseMatch = new AjaxCheckBoxPanel( + "ignoreCaseMatch", "ignoreCaseMatch", new PropertyModel<>(resourceProvision, "ignoreCaseMatch")); + container.add(ignoreCaseMatch); } } @@ -101,12 +105,12 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ResourceProvision> private final ResourceProvision provision; - AuxClasses(final ResourceProvision item) { - this.provision = item; + AuxClasses(final ResourceProvision resourceProvision) { + this.provision = resourceProvision; setTitleModel(new ResourceModel("auxClasses.title")); - setSummaryModel(new StringResourceModel("auxClasses.summary", this, new Model<>(item))); - add(new ProvisionAuxClassesPanel("auxClasses", item.getProvisionTO())); + setSummaryModel(new StringResourceModel("auxClasses.summary", this, new Model<>(resourceProvision))); + add(new ProvisionAuxClassesPanel("auxClasses", resourceProvision.getProvisionTO())); } @Override @@ -122,7 +126,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ResourceProvision> private static final long serialVersionUID = 3454904947720856253L; - Mapping(final ResourceProvision item) { + Mapping(final ResourceProvision resourceProvision) { setTitleModel(Model.of("Mapping")); setSummaryModel(Model.of(StringUtils.EMPTY)); } @@ -135,16 +139,16 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ResourceProvision> private static final long serialVersionUID = 2359955465172450478L; - ConnObjectLink(final ResourceProvision item) { + ConnObjectLink(final ResourceProvision resourceProvision) { super(new ResourceModel("link.title", StringUtils.EMPTY), new ResourceModel("link.summary", StringUtils.EMPTY)); - final WebMarkupContainer connObjectLinkContainer = new WebMarkupContainer("connObjectLinkContainer"); + WebMarkupContainer connObjectLinkContainer = new WebMarkupContainer("connObjectLinkContainer"); connObjectLinkContainer.setOutputMarkupId(true); add(connObjectLinkContainer); boolean connObjectLinkEnabled = false; - if (StringUtils.isNotBlank(item.getConnObjectLink())) { + if (StringUtils.isNotBlank(resourceProvision.getConnObjectLink())) { connObjectLinkEnabled = true; } @@ -160,7 +164,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ResourceProvision> final AjaxTextFieldPanel connObjectLink = new AjaxTextFieldPanel( "connObjectLink", new ResourceModel("connObjectLink", "connObjectLink").getObject(), - new PropertyModel<>(item, "connObjectLink"), + new PropertyModel<>(resourceProvision, "connObjectLink"), false); connObjectLink.enableJexlHelp(); connObjectLink.setEnabled(connObjectLinkEnabled); @@ -195,57 +199,57 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ResourceProvision> } @Override - protected WizardModel buildModelSteps(final ResourceProvision modelObject, final WizardModel wizardModel) { - wizardModel.add(new ObjectType(modelObject)); - wizardModel.add(new AuxClasses(modelObject)); + protected WizardModel buildModelSteps(final ResourceProvision resourceProvision, final WizardModel wizardModel) { + wizardModel.add(new ObjectType(resourceProvision)); + wizardModel.add(new AuxClasses(resourceProvision)); - Mapping mapping = new Mapping(modelObject); + Mapping mapping = new Mapping(resourceProvision); mapping.setOutputMarkupId(true); ItemTransformersTogglePanel itemTransformers = new ItemTransformersTogglePanel(mapping, pageRef); addOuterObject(itemTransformers); JEXLTransformersTogglePanel jexlTransformers = new JEXLTransformersTogglePanel(mapping, pageRef); addOuterObject(jexlTransformers); - if (modelObject.getProvisionTO() != null && modelObject.getProvisionTO().getMapping() == null) { - modelObject.getProvisionTO().setMapping(new MappingTO()); + if (resourceProvision.getProvisionTO() != null && resourceProvision.getProvisionTO().getMapping() == null) { + resourceProvision.getProvisionTO().setMapping(new MappingTO()); } mapping.add(new ResourceMappingPanel( - "mapping", resourceTO, adminRealm, modelObject, itemTransformers, jexlTransformers)); + "mapping", resourceTO, adminRealm, resourceProvision, itemTransformers, jexlTransformers)); wizardModel.add(mapping); - wizardModel.add(new ConnObjectLink(modelObject)); + wizardModel.add(new ConnObjectLink(resourceProvision)); return wizardModel; } @Override - protected Serializable onApplyInternal(final ResourceProvision modelObject) { - if (modelObject.getOrgUnitTO() != null) { - this.resourceTO.setOrgUnit(modelObject.getOrgUnitTO()); + protected Serializable onApplyInternal(final ResourceProvision resourceProvision) { + if (resourceProvision.getOrgUnitTO() != null) { + this.resourceTO.setOrgUnit(resourceProvision.getOrgUnitTO()); this.resourceTO.getOrgUnit().getItems().clear(); - this.resourceTO.getOrgUnit().getItems().addAll(modelObject.getItems()); - } else if (modelObject.getProvisionTO() != null) { + this.resourceTO.getOrgUnit().getItems().addAll(resourceProvision.getItems()); + } else if (resourceProvision.getProvisionTO() != null) { final List<ProvisionTO> provisions; - if (modelObject.getKey() == null) { + if (resourceProvision.getKey() == null) { provisions = this.resourceTO.getProvisions().stream(). - filter(object -> !modelObject.getAnyType().equals(object.getAnyType())). + filter(object -> !resourceProvision.getAnyType().equals(object.getAnyType())). collect(Collectors.toList()); } else { provisions = this.resourceTO.getProvisions().stream(). - filter(object -> !modelObject.getKey().equals(object.getKey())). + filter(object -> !resourceProvision.getKey().equals(object.getKey())). collect(Collectors.toList()); } - ProvisionTO provisionTO = modelObject.getProvisionTO(); + ProvisionTO provisionTO = resourceProvision.getProvisionTO(); provisionTO.getMapping().getItems().clear(); - provisionTO.getMapping().getItems().addAll(modelObject.getItems()); + provisionTO.getMapping().getItems().addAll(resourceProvision.getItems()); provisions.add(provisionTO); this.resourceTO.getProvisions().clear(); this.resourceTO.getProvisions().addAll(provisions); } - return modelObject; + return resourceProvision; } } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java index 6a36f62..270f32d 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java @@ -142,13 +142,13 @@ public class ResourceMappingPanel extends AbstractMappingPanel { LOG.error("Could not read AnyType classes for {}", anyType.getClasses(), e); } } - for (String auxClass : provision.getAuxClasses()) { + provision.getAuxClasses().forEach(auxClass -> { try { anyTypeClassTOs.add(anyTypeClassRestClient.read(auxClass)); } catch (Exception e) { LOG.error("Could not read AnyTypeClass for {}", auxClass, e); } - } + }); switch (provision.getAnyType()) { case "USER": @@ -163,14 +163,14 @@ public class ResourceMappingPanel extends AbstractMappingPanel { choices.addAll(ANY_OBJECT_FIELD_NAMES); } - for (AnyTypeClassTO anyTypeClassTO : anyTypeClassTOs) { + anyTypeClassTOs.forEach(anyTypeClassTO -> { choices.addAll(anyTypeClassTO.getPlainSchemas()); choices.addAll(anyTypeClassTO.getDerSchemas()); choices.addAll(anyTypeClassTO.getVirSchemas()); - } + }); } - final List<String> names = new ArrayList<>(choices); + List<String> names = new ArrayList<>(choices); Collections.sort(names); toBeUpdated.setChoices(names); } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java index 796fb76..e4233b5 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java @@ -128,6 +128,18 @@ public class ResourceProvision implements Serializable { return provisionTO == null ? Collections.<String>emptyList() : provisionTO.getAuxClasses(); } + public boolean isIgnoreCaseMatch() { + return provisionTO == null ? orgUnitTO.isIgnoreCaseMatch() : provisionTO.isIgnoreCaseMatch(); + } + + public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) { + if (provisionTO == null) { + orgUnitTO.setIgnoreCaseMatch(ignoreCaseMatch); + } else { + provisionTO.setIgnoreCaseMatch(ignoreCaseMatch); + } + } + public String getConnObjectLink() { return provisionTO == null ? orgUnitTO == null http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.html ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.html index c5ff7b1..d88d469 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.html +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.html @@ -21,6 +21,7 @@ under the License. <div wicket:id="container"> <div class="form-group"> <span wicket:id="clazz"/> + <span wicket:id="ignoreCaseMatch"/> </div> </div> </wicket:panel> http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.properties ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.properties index 08d4d61..a43e8f0 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType.properties @@ -20,3 +20,4 @@ clazz.summary= clazz=Object Class clazz.Required=Object class is required +ignoreCaseMatch=Ignore case for value match http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_it.properties ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_it.properties index 3219b30..930ff67 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_it.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_it.properties @@ -20,3 +20,4 @@ clazz.summary= clazz=Object Class clazz.Required=Object class \u00e8 richiesto +ignoreCaseMatch=Corrispondenza dei valori maiuscole / minuscole http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ja.properties ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ja.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ja.properties index 22cb967..2776989 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ja.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ja.properties @@ -20,3 +20,4 @@ clazz.summary= clazz=\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30af\u30e9\u30b9 clazz.Required=\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30af\u30e9\u30b9\u304c\u5fc5\u8981\u3067\u3059 +ignoreCaseMatch=Ignore case for value match http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_pt_BR.properties ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_pt_BR.properties index 7e16e5c..2bf167c 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_pt_BR.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_pt_BR.properties @@ -20,3 +20,4 @@ clazz.summary= clazz=Object Class clazz.Required=Object class \u00e9 necess\u00e1ria +ignoreCaseMatch=Ignore case for value match http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ru.properties ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ru.properties index dd86e10..4b683e8 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ru.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder$ObjectType_ru.properties @@ -20,3 +20,4 @@ clazz.summary= clazz=Object Class clazz.Required=Object class \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e +ignoreCaseMatch=Ignore case for value match http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java index c3be6f2..7e5585a 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java @@ -49,7 +49,7 @@ public class MappingTO extends AbstractBaseBean implements ItemContainerTO { @Override public ItemTO getConnObjectKeyItem() { - return getItems().stream().filter(item -> item.isConnObjectKey()).findFirst().get(); + return getItems().stream().filter(ItemTO::isConnObjectKey).findFirst().get(); } protected boolean addConnObjectKeyItem(final ItemTO connObjectItem) { http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java index ae4255f..f7e326b 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java @@ -39,6 +39,8 @@ public class OrgUnitTO extends AbstractBaseBean implements EntityTO, ItemContain private String syncToken; + private boolean ignoreCaseMatch; + private String connObjectLink; private final List<ItemTO> items = new ArrayList<>(); @@ -69,6 +71,14 @@ public class OrgUnitTO extends AbstractBaseBean implements EntityTO, ItemContain this.syncToken = syncToken; } + public boolean isIgnoreCaseMatch() { + return ignoreCaseMatch; + } + + public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) { + this.ignoreCaseMatch = ignoreCaseMatch; + } + public String getConnObjectLink() { return connObjectLink; } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java index b7dae9c..cf9293e 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java @@ -43,6 +43,8 @@ public class ProvisionTO extends AbstractBaseBean implements EntityTO { private String syncToken; + private boolean ignoreCaseMatch; + private MappingTO mapping; private final List<String> virSchemas = new ArrayList<>(); @@ -88,6 +90,14 @@ public class ProvisionTO extends AbstractBaseBean implements EntityTO { this.syncToken = syncToken; } + public boolean isIgnoreCaseMatch() { + return ignoreCaseMatch; + } + + public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) { + this.ignoreCaseMatch = ignoreCaseMatch; + } + public MappingTO getMapping() { return mapping; } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java index 88adeaa..34b1409 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java @@ -150,6 +150,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<AbstractBase ConnectorObject connectorObject = connector.getObject( provision.getObjectClass(), AttributeBuilder.build(connObjectKeyItem.getExtAttrName(), connObjectKeyValue), + provision.isIgnoreCaseMatch(), MappingUtils.buildOperationOptions(mapItems)); if (connectorObject != null) { Set<Attribute> attributes = connectorObject.getAttributes(); http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java index e90b245..bea59db 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java @@ -331,6 +331,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> { ConnectorObject connectorObject = connector.getObject( init.getRight().getObjectClass(), AttributeBuilder.build(connObjectKeyItem.get().getExtAttrName(), connObjectKeyValue.get()), + init.getRight().isIgnoreCaseMatch(), MappingUtils.buildOperationOptions(mapItems)); if (connectorObject == null) { throw new NotFoundException( http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java index 658a32b..042a799 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java @@ -41,9 +41,9 @@ public interface AnyDAO<A extends Any<?>> extends DAO<A> { A findByWorkflowId(String workflowId); - List<A> findByPlainAttrValue(String schemaName, PlainAttrValue attrValue); + List<A> findByPlainAttrValue(String schemaName, PlainAttrValue attrValue, boolean ignoreCaseMatch); - A findByPlainAttrUniqueValue(String schemaName, PlainAttrValue attrUniqueValue); + A findByPlainAttrUniqueValue(String schemaName, PlainAttrValue attrUniqueValue, boolean ignoreCaseMatch); /** * Find any objects by derived attribute value. This method could fail if one or more string literals contained @@ -53,9 +53,10 @@ public interface AnyDAO<A extends Any<?>> extends DAO<A> { * * @param schemaName derived schema name * @param value derived attribute value + * @param ignoreCaseMatch whether comparison for string values should take case into account or not * @return list of any objects */ - List<A> findByDerAttrValue(String schemaName, String value); + List<A> findByDerAttrValue(String schemaName, String value, boolean ignoreCaseMatch); List<A> findByResource(ExternalResource resource); http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java index 89bf153..52e209b 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java @@ -40,6 +40,10 @@ public interface OrgUnit extends Entity { void setSyncToken(SyncToken syncToken); + boolean isIgnoreCaseMatch(); + + void setIgnoreCaseMatch(boolean ignoreCaseMatch); + String getConnObjectLink(); void setConnObjectLink(String connObjectLink); http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java index 0a89878..1fe6023 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java @@ -49,6 +49,10 @@ public interface Provision extends Entity { void setSyncToken(SyncToken syncToken); + boolean isIgnoreCaseMatch(); + + void setIgnoreCaseMatch(boolean ignoreCaseMatch); + Mapping getMapping(); void setMapping(Mapping mapping); http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java index 53fb4a9..a59b33a 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java @@ -195,19 +195,27 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im return result; } - private Query findByPlainAttrValueQuery(final String entityName) { - return entityManager().createQuery("SELECT e FROM " + entityName + " e" + private Query findByPlainAttrValueQuery(final String entityName, final boolean ignoreCaseMatch) { + String query = "SELECT e FROM " + entityName + " e" + " WHERE e.attribute.schema.id = :schemaKey AND (e.stringValue IS NOT NULL" - + " AND e.stringValue = :stringValue)" + + " AND " + + (ignoreCaseMatch ? "LOWER(" : "") + "e.stringValue" + (ignoreCaseMatch ? ")" : "") + + " = " + + (ignoreCaseMatch ? "LOWER(" : "") + ":stringValue" + (ignoreCaseMatch ? ")" : "") + ")" + " OR (e.booleanValue IS NOT NULL AND e.booleanValue = :booleanValue)" + " OR (e.dateValue IS NOT NULL AND e.dateValue = :dateValue)" + " OR (e.longValue IS NOT NULL AND e.longValue = :longValue)" - + " OR (e.doubleValue IS NOT NULL AND e.doubleValue = :doubleValue)"); + + " OR (e.doubleValue IS NOT NULL AND e.doubleValue = :doubleValue)"; + return entityManager().createQuery(query); } @Override @SuppressWarnings("unchecked") - public List<A> findByPlainAttrValue(final String schemaKey, final PlainAttrValue attrValue) { + public List<A> findByPlainAttrValue( + final String schemaKey, + final PlainAttrValue attrValue, + final boolean ignoreCaseMatch) { + PlainSchema schema = plainSchemaDAO().find(schemaKey); if (schema == null) { LOG.error("Invalid schema name '{}'", schemaKey); @@ -217,7 +225,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im String entityName = schema.isUniqueConstraint() ? anyUtils().plainAttrUniqueValueClass().getName() : anyUtils().plainAttrValueClass().getName(); - Query query = findByPlainAttrValueQuery(entityName); + Query query = findByPlainAttrValueQuery(entityName, ignoreCaseMatch); query.setParameter("schemaKey", schemaKey); query.setParameter("stringValue", attrValue.getStringValue()); query.setParameter("booleanValue", attrValue.getBooleanValue() == null @@ -243,7 +251,11 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im } @Override - public A findByPlainAttrUniqueValue(final String schemaKey, final PlainAttrValue attrUniqueValue) { + public A findByPlainAttrUniqueValue( + final String schemaKey, + final PlainAttrValue attrUniqueValue, + final boolean ignoreCaseMatch) { + PlainSchema schema = plainSchemaDAO().find(schemaKey); if (schema == null) { LOG.error("Invalid schema name '{}'", schemaKey); @@ -254,7 +266,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im return null; } - List<A> result = findByPlainAttrValue(schemaKey, attrUniqueValue); + List<A> result = findByPlainAttrValue(schemaKey, attrUniqueValue, ignoreCaseMatch); return result.isEmpty() ? null : result.iterator().next(); @@ -283,15 +295,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im return attrValues; } - /** - * Generate one where clause for each different attribute schema into the derived schema expression provided. - * - * @param expression derived schema expression - * @param value derived attribute value - * @param attrUtils USER / GROUP - * @return where clauses to use to build the query - */ - private Set<String> getWhereClause(final String expression, final String value) { + private Set<String> getWhereClause(final String expression, final String value, final boolean ignoreCaseMatch) { Parser parser = new Parser(new StringReader(expression)); // Schema names @@ -386,10 +390,16 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im bld.append("v.dateValue = '").append(attrValues.get(i)).append("'"); break; default: - bld.append("v.stringValue = '").append(attrValues.get(i)).append("'"); + if (ignoreCaseMatch) { + bld.append("LOWER(v.stringValue) = '"). + append(attrValues.get(i).toLowerCase()).append("'"); + } else { + bld.append("v.stringValue = '"). + append(attrValues.get(i)).append("'"); + } } - bld.append(")"); + bld.append(')'); used.add(identifiers.get(i)); @@ -404,7 +414,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im } @Override - public List<A> findByDerAttrValue(final String schemaKey, final String value) { + public List<A> findByDerAttrValue(final String schemaKey, final String value, final boolean ignoreCaseMatch) { DerSchema schema = derSchemaDAO().find(schemaKey); if (schema == null) { LOG.error("Invalid schema name '{}'", schemaKey); @@ -415,7 +425,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im StringBuilder querystring = new StringBuilder(); boolean subquery = false; - for (String clause : getWhereClause(schema.getExpression(), value)) { + for (String clause : getWhereClause(schema.getExpression(), value, ignoreCaseMatch)) { if (querystring.length() > 0) { subquery = true; querystring.append(" AND a.owner_id IN ( "); http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java index 6a76358..89939fb 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java @@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity.resource; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import javax.persistence.Basic; import javax.persistence.Cacheable; import javax.persistence.CascadeType; import javax.persistence.Entity; @@ -29,6 +30,8 @@ import javax.persistence.Lob; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem; @@ -56,6 +59,11 @@ public class JPAOrgUnit extends AbstractGeneratedKeyEntity implements OrgUnit { @Lob private String serializedSyncToken; + @Basic + @Min(0) + @Max(1) + private Integer ignoreCaseMatch; + @NotNull private String connObjectLink; @@ -103,6 +111,16 @@ public class JPAOrgUnit extends AbstractGeneratedKeyEntity implements OrgUnit { } @Override + public boolean isIgnoreCaseMatch() { + return isBooleanAsInteger(ignoreCaseMatch); + } + + @Override + public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) { + this.ignoreCaseMatch = getBooleanAsInteger(ignoreCaseMatch); + } + + @Override public String getConnObjectLink() { return connObjectLink; } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java index 5c10f51..16e85c8 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java @@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.entity.resource; import java.util.ArrayList; import java.util.List; +import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -31,6 +32,8 @@ import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.UniqueConstraint; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; import org.apache.syncope.core.persistence.api.entity.AnyType; @@ -72,6 +75,11 @@ public class JPAProvision extends AbstractGeneratedKeyEntity implements Provisio @Lob private String serializedSyncToken; + @Basic + @Min(0) + @Max(1) + private Integer ignoreCaseMatch; + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "provision") private JPAMapping mapping; @@ -138,6 +146,16 @@ public class JPAProvision extends AbstractGeneratedKeyEntity implements Provisio } @Override + public boolean isIgnoreCaseMatch() { + return isBooleanAsInteger(ignoreCaseMatch); + } + + @Override + public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) { + this.ignoreCaseMatch = getBooleanAsInteger(ignoreCaseMatch); + } + + @Override public Mapping getMapping() { return mapping; } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java index fa32394..47f47d8 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java @@ -88,36 +88,50 @@ public class UserTest extends AbstractTest { } @Test - public void findByDerAttributeValue() { - final List<User> list = userDAO.findByDerAttrValue("cn", "Vivaldi, Antonio"); + public void findByDerAttrValue() { + List<User> list = userDAO.findByDerAttrValue("cn", "Vivaldi, Antonio", false); + assertEquals(1, list.size()); + + list = userDAO.findByDerAttrValue("cn", "VIVALDI, ANTONIO", false); + assertEquals(0, list.size()); + + list = userDAO.findByDerAttrValue("cn", "VIVALDI, ANTONIO", true); assertEquals(1, list.size()); } @Test public void findByInvalidDerAttrValue() { - assertTrue(userDAO.findByDerAttrValue("cn", "Antonio, Maria, Rossi").isEmpty()); + assertTrue(userDAO.findByDerAttrValue("cn", "Antonio, Maria, Rossi", false).isEmpty()); } @Test public void findByInvalidDerAttrExpression() { - assertTrue(userDAO.findByDerAttrValue("noschema", "Antonio, Maria").isEmpty()); + assertTrue(userDAO.findByDerAttrValue("noschema", "Antonio, Maria", false).isEmpty()); } @Test - public void findByAttributeValue() { - final UPlainAttrValue fullnameValue = entityFactory.newEntity(UPlainAttrValue.class); + public void findByPlainAttrValue() { + UPlainAttrValue fullnameValue = entityFactory.newEntity(UPlainAttrValue.class); fullnameValue.setStringValue("Gioacchino Rossini"); - final List<User> list = userDAO.findByPlainAttrValue("fullname", fullnameValue); + List<User> list = userDAO.findByPlainAttrValue("fullname", fullnameValue, false); + assertEquals(1, list.size()); + + fullnameValue.setStringValue("Gioacchino ROSSINI"); + + list = userDAO.findByPlainAttrValue("fullname", fullnameValue, false); + assertEquals(0, list.size()); + + list = userDAO.findByPlainAttrValue("fullname", fullnameValue, true); assertEquals(1, list.size()); } @Test - public void findByAttributeBooleanValue() { + public void findByPlainAttrBooleanValue() { final UPlainAttrValue coolValue = entityFactory.newEntity(UPlainAttrValue.class); coolValue.setBooleanValue(true); - final List<User> list = userDAO.findByPlainAttrValue("cool", coolValue); + final List<User> list = userDAO.findByPlainAttrValue("cool", coolValue, false); assertEquals(1, list.size()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java index eddafed..561e089 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java @@ -241,11 +241,11 @@ public class UserTest extends AbstractTest { assertNotNull(firstname); // search by ksuffix derived attribute - List<User> list = userDAO.findByDerAttrValue("ksuffix", firstname + "k"); + List<User> list = userDAO.findByDerAttrValue("ksuffix", firstname + "k", false); assertEquals(1, list.size()); // search by kprefix derived attribute - list = userDAO.findByDerAttrValue("kprefix", "k" + firstname); + list = userDAO.findByDerAttrValue("kprefix", "k" + firstname, false); assertEquals(1, list.size()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java index a0b21cb..b699c87 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java @@ -143,10 +143,15 @@ public interface Connector { * * @param objectClass ConnId's object class * @param connObjectKey ConnId's key attribute + * @param ignoreCaseMatch whether match should be performed regardless of the value case * @param options ConnId's OperationOptions * @return ConnId's connector object for given uid */ - ConnectorObject getObject(ObjectClass objectClass, Attribute connObjectKey, OperationOptions options); + ConnectorObject getObject( + ObjectClass objectClass, + Attribute connObjectKey, + boolean ignoreCaseMatch, + OperationOptions options); /** * Search for remote objects. http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AsyncConnectorFacade.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AsyncConnectorFacade.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AsyncConnectorFacade.java index 79fbd23..22cc25d 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AsyncConnectorFacade.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AsyncConnectorFacade.java @@ -100,13 +100,17 @@ public class AsyncConnectorFacade { final ConnectorFacade connector, final ObjectClass objectClass, final Attribute connObjectKey, + final boolean ignoreCaseMatch, final OperationOptions options) { ConnectorObject[] objects = new ConnectorObject[1]; - connector.search(objectClass, FilterBuilder.equalTo(connObjectKey), connectorObject -> { - objects[0] = connectorObject; - return false; - }, options); + connector.search( + objectClass, + ignoreCaseMatch ? FilterBuilder.equalsIgnoreCase(connObjectKey) : FilterBuilder.equalTo(connObjectKey), + connectorObject -> { + objects[0] = connectorObject; + return false; + }, options); return new AsyncResult<>(objects[0]); } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java index 523ecc0..dfca75d 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java @@ -392,12 +392,13 @@ public class ConnectorFacadeProxy implements Connector { public ConnectorObject getObject( final ObjectClass objectClass, final Attribute connObjectKey, + final boolean ignoreCaseMatch, final OperationOptions options) { Future<ConnectorObject> future = null; if (connInstance.getCapabilities().contains(ConnectorCapability.SEARCH)) { - future = asyncFacade.getObject(connector, objectClass, connObjectKey, options); + future = asyncFacade.getObject(connector, objectClass, connObjectKey, ignoreCaseMatch, options); } else { LOG.info("Search was attempted, although the connector only has these capabilities: {}. No action.", connInstance.getCapabilities()); http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java index 0977a60..b6c29ee 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java @@ -74,7 +74,7 @@ public class VirAttrHandlerImpl implements VirAttrHandler { Map<Provision, Set<VirSchema>> toRead = new HashMap<>(); - for (VirSchema schema : schemas) { + schemas.forEach(schema -> { if (ownedResources.contains(schema.getProvision().getResource())) { VirAttrCacheValue virAttrCacheValue = virAttrCache.get(any.getType().getKey(), any.getKey(), schema.getKey()); @@ -94,35 +94,36 @@ public class VirAttrHandlerImpl implements VirAttrHandler { LOG.debug("Not considering {} since {} is not assigned to {}", schema, any, schema.getProvision().getResource()); } - } + }); - for (Map.Entry<Provision, Set<VirSchema>> entry : toRead.entrySet()) { - LOG.debug("About to read from {}: {}", entry.getKey(), entry.getValue()); + toRead.forEach((provision, schemasToRead) -> { + LOG.debug("About to read from {}: {}", provision, schemasToRead); - Optional<MappingItem> connObjectKeyItem = MappingUtils.getConnObjectKeyItem(entry.getKey()); + Optional<MappingItem> connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision); String connObjectKeyValue = connObjectKeyItem.isPresent() - ? mappingManager.getConnObjectKeyValue(any, entry.getKey()).orElse(null) + ? mappingManager.getConnObjectKeyValue(any, provision).orElse(null) : null; if (!connObjectKeyItem.isPresent() || connObjectKeyValue == null) { - LOG.error("No ConnObjectKey or value found for {}, ignoring...", entry.getKey()); + LOG.error("No ConnObjectKey or value found for {}, ignoring...", provision); } else { Set<MappingItem> linkingMappingItems = new HashSet<>(); linkingMappingItems.add(connObjectKeyItem.get()); - linkingMappingItems.addAll(entry.getValue().stream(). + linkingMappingItems.addAll(schemasToRead.stream(). map(schema -> schema.asLinkingMappingItem()).collect(Collectors.toSet())); - Connector connector = connFactory.getConnector(entry.getKey().getResource()); + Connector connector = connFactory.getConnector(provision.getResource()); try { ConnectorObject connectorObject = connector.getObject( - entry.getKey().getObjectClass(), + provision.getObjectClass(), AttributeBuilder.build(connObjectKeyItem.get().getExtAttrName(), connObjectKeyValue), + provision.isIgnoreCaseMatch(), MappingUtils.buildOperationOptions(linkingMappingItems.iterator())); if (connectorObject == null) { LOG.debug("No read from {} with filter '{} == {}'", - entry.getKey(), connObjectKeyItem.get().getExtAttrName(), connObjectKeyValue); + provision, connObjectKeyItem.get().getExtAttrName(), connObjectKeyValue); } else { - entry.getValue().forEach(schema -> { + schemasToRead.forEach(schema -> { Attribute attr = connectorObject.getAttributeByName(schema.getExtAttrName()); if (attr != null) { VirAttrCacheValue virAttrCacheValue = new VirAttrCacheValue(); @@ -137,10 +138,10 @@ public class VirAttrHandlerImpl implements VirAttrHandler { }); } } catch (Exception e) { - LOG.error("Error reading from {}", entry.getKey(), e); + LOG.error("Error reading from {}", provision, e); } } - } + }); return result; } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java index 6154658..122e153 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java @@ -197,6 +197,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder { provision.getAuxClasses(). removeIf(anyTypeClass -> !provisionTO.getAuxClasses().contains(anyTypeClass.getKey())); + provision.setIgnoreCaseMatch(provisionTO.isIgnoreCaseMatch()); + if (provisionTO.getMapping() == null) { provision.setMapping(null); } else { @@ -280,6 +282,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder { } orgUnit.setObjectClass(new ObjectClass(orgUnitTO.getObjectClass())); + orgUnit.setIgnoreCaseMatch(orgUnitTO.isIgnoreCaseMatch()); + if (orgUnitTO.getConnObjectLink() == null) { SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidOrgUnit); sce.getElements().add("Null connObjectLink"); @@ -594,6 +598,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder { provisionTO.getAuxClasses().addAll(provision.getAuxClasses().stream(). map(cls -> cls.getKey()).collect(Collectors.toList())); provisionTO.setSyncToken(provision.getSerializedSyncToken()); + provisionTO.setIgnoreCaseMatch(provision.isIgnoreCaseMatch()); if (provision.getMapping() != null) { MappingTO mappingTO = new MappingTO(); @@ -625,6 +630,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder { orgUnitTO.setKey(orgUnit.getKey()); orgUnitTO.setObjectClass(orgUnit.getObjectClass().getObjectClassValue()); orgUnitTO.setSyncToken(orgUnit.getSerializedSyncToken()); + orgUnitTO.setIgnoreCaseMatch(orgUnit.isIgnoreCaseMatch()); orgUnitTO.setConnObjectLink(orgUnit.getConnObjectLink()); populateItems(orgUnit.getItems(), orgUnitTO); http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java index da358fd..63c6457 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReconciliationReportlet.java @@ -296,6 +296,7 @@ public class ReconciliationReportlet extends AbstractReportlet { ConnectorObject connectorObject = connector.getObject( provision.getObjectClass(), AttributeBuilder.build(connObjectKeyItem.get().getExtAttrName(), connObjectKeyValue), + provision.isIgnoreCaseMatch(), MappingUtils.buildOperationOptions(provision.getMapping().getItems().iterator())); if (connectorObject == null) { http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java index 4a43019..a3e7132 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java @@ -606,6 +606,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask obj = connector.getObject( new ObjectClass(task.getObjectClassName()), AttributeBuilder.build(connObjectKeyItem.get().getExtAttrName(), connObjectKey), + provision.isIgnoreCaseMatch(), MappingUtils.buildOperationOptions(new IteratorChain<>( MappingUtils.getPropagationItems(provision.getMapping().getItems()).iterator(), linkingMappingItems.iterator()))); @@ -656,6 +657,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask try { obj = connector.getObject(new ObjectClass(task.getObjectClassName()), AttributeBuilder.build(connObjectKeyItem.get().getExtAttrName(), connObjectKey), + orgUnit.isIgnoreCaseMatch(), MappingUtils.buildOperationOptions( MappingUtils.getPropagationItems(orgUnit.getItems()).iterator())); } catch (TimeoutException toe) { http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java index 63f397b..2c10a12 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java @@ -199,6 +199,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan final ObjectClass objectClass, final String connObjectKey, final String connObjectKeyValue, + final boolean ignoreCaseMatch, final Iterator<? extends Item> iterator) { ConnectorObject obj = null; @@ -206,6 +207,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan obj = profile.getConnector().getObject( objectClass, AttributeBuilder.build(connObjectKey, connObjectKeyValue), + ignoreCaseMatch, MappingUtils.buildOperationOptions(iterator)); } catch (TimeoutException toe) { LOG.debug("Request timeout", toe); @@ -272,6 +274,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan provision.get().getObjectClass(), connObjectKey.get().getExtAttrName(), connObjecKeyValue.get(), + provision.get().isIgnoreCaseMatch(), provision.get().getMapping().getItems().iterator()); } else { LOG.debug("ConnObjectKeyItem {} or its value {} are null", connObjectKey, connObjecKeyValue); @@ -445,6 +448,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan provision.get().getObjectClass(), connObjectKey.get().getExtAttrName(), connObjecKeyValue.get(), + provision.get().isIgnoreCaseMatch(), provision.get().getMapping().getItems().iterator()); } } catch (IgnoreProvisionException e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java index 434d275..2a4a510 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java @@ -163,6 +163,7 @@ public class DefaultRealmPushResultHandler final ObjectClass objectClass, final String connObjectKey, final String connObjectKeyValue, + final boolean ignoreCaseMatch, final Iterator<? extends Item> iterator) { ConnectorObject obj = null; @@ -170,6 +171,7 @@ public class DefaultRealmPushResultHandler obj = profile.getConnector().getObject( objectClass, AttributeBuilder.build(connObjectKey, connObjectKeyValue), + ignoreCaseMatch, MappingUtils.buildOperationOptions(iterator)); } catch (TimeoutException toe) { LOG.debug("Request timeout", toe); @@ -205,6 +207,7 @@ public class DefaultRealmPushResultHandler orgUnit.getObjectClass(), connObjectKey.get().getExtAttrName(), connObjecKeyValue.get(), + orgUnit.isIgnoreCaseMatch(), orgUnit.getItems().iterator()); } else { LOG.debug("OrgUnitItem {} or its value {} are null", connObjectKey, connObjecKeyValue); @@ -383,6 +386,7 @@ public class DefaultRealmPushResultHandler orgUnit.getObjectClass(), connObjectKey.get().getExtAttrName(), connObjecKeyValue.get(), + orgUnit.isIgnoreCaseMatch(), orgUnit.getItems().iterator()); } } catch (IgnoreProvisionException e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java index fd66d1f..301e33f 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java @@ -105,7 +105,7 @@ public class LDAPMembershipPullActions extends SchedulingPullActions { if (membAttr == null) { OperationOptionsBuilder oob = new OperationOptionsBuilder(); oob.setAttributesToGet(groupMemberName); - ConnectorObject remoteObj = connector.getObject(ObjectClass.GROUP, delta.getUid(), oob.build()); + ConnectorObject remoteObj = connector.getObject(ObjectClass.GROUP, delta.getUid(), false, oob.build()); if (remoteObj == null) { LOG.debug("Object for '{}' not found", delta.getUid().getUidValue()); } else { @@ -177,7 +177,8 @@ public class LDAPMembershipPullActions extends SchedulingPullActions { anyTypeDAO.findUser(), name, profile.getTask().getResource(), - profile.getConnector()); + profile.getConnector(), + false); if (userKey.isPresent()) { resolvedMemberships.put(userKey.get(), memb); } else { http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java index f8b73a2..95a4dc1 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java @@ -30,6 +30,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.collections.IteratorChain; import org.apache.syncope.common.lib.types.ConflictResolutionAction; import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; @@ -123,7 +124,11 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i return status.get(); } - protected void setGroupOwners(final GroupPullResultHandler ghandler) { + protected void setGroupOwners( + final GroupPullResultHandler ghandler, + final boolean userIgnoreCaseMatch, + final boolean groupIgnoreCaseMatch) { + ghandler.getGroupOwnerMap().entrySet().stream().map(entry -> { Group group = groupDAO.find(entry.getKey()); if (group == null) { @@ -137,7 +142,8 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i anyTypeDAO.findUser(), entry.getValue(), ghandler.getProfile().getTask().getResource(), - ghandler.getProfile().getConnector()); + ghandler.getProfile().getConnector(), + userIgnoreCaseMatch); if (userKey.isPresent()) { group.setUserOwner(userDAO.find(userKey.get())); @@ -146,7 +152,8 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i anyTypeDAO.findGroup(), entry.getValue(), ghandler.getProfile().getTask().getResource(), - ghandler.getProfile().getConnector()); + ghandler.getProfile().getConnector(), + groupIgnoreCaseMatch); if (groupKey.isPresent()) { group.setGroupOwner(groupDAO.find(groupKey.get())); @@ -272,8 +279,16 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i // ...then provisions for any types SyncopePullResultHandler handler; GroupPullResultHandler ghandler = buildGroupHandler(); + boolean userIgnoreCaseMatch = false; + boolean groupIgnoreCaseMatch = false; for (Provision provision : pullTask.getResource().getProvisions()) { if (provision.getMapping() != null) { + if (provision.getAnyType().getKind() == AnyTypeKind.USER) { + userIgnoreCaseMatch = provision.isIgnoreCaseMatch(); + } else if (provision.getAnyType().getKind() == AnyTypeKind.GROUP) { + groupIgnoreCaseMatch = provision.isIgnoreCaseMatch(); + } + status.set("Pulling " + provision.getObjectClass().getObjectClassValue()); switch (provision.getAnyType().getKind()) { @@ -340,7 +355,7 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i } } try { - setGroupOwners(ghandler); + setGroupOwners(ghandler, userIgnoreCaseMatch, groupIgnoreCaseMatch); } catch (Exception e) { LOG.error("While setting group owners", e); } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java index 941e5e4..0d61f1b 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java @@ -58,16 +58,19 @@ import org.identityconnectors.framework.common.objects.AttributeUtil; import org.identityconnectors.framework.common.objects.ConnectorObject; import org.identityconnectors.framework.common.objects.Name; import org.identityconnectors.framework.common.objects.OperationalAttributes; -import org.identityconnectors.framework.common.objects.filter.EqualsFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.apache.syncope.core.persistence.api.dao.PullCorrelationRule; +import org.apache.syncope.core.persistence.api.dao.search.AnyCond; +import org.apache.syncope.core.persistence.api.dao.search.AttributeCond; +import org.apache.syncope.core.persistence.api.dao.search.SearchCond; import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.apache.syncope.core.provisioning.api.data.ItemTransformer; import org.apache.syncope.core.spring.ImplementationManager; +import org.identityconnectors.framework.common.objects.filter.FilterBuilder; @Transactional(readOnly = true) @Component @@ -118,7 +121,8 @@ public class PullUtils { final AnyType anyType, final String name, final ExternalResource resource, - final Connector connector) { + final Connector connector, + final boolean ignoreCaseMatch) { Optional<? extends Provision> provision = resource.getProvision(anyType); if (!provision.isPresent()) { @@ -129,9 +133,11 @@ public class PullUtils { AnyUtils anyUtils = anyUtilsFactory.getInstance(anyType.getKind()); - final List<ConnectorObject> found = new ArrayList<>(); + List<ConnectorObject> found = new ArrayList<>(); + Name nameAttr = new Name(name); connector.search(provision.get().getObjectClass(), - new EqualsFilter(new Name(name)), obj -> found.add(obj), + ignoreCaseMatch ? FilterBuilder.equalsIgnoreCase(nameAttr) : FilterBuilder.equalTo(nameAttr), + obj -> found.add(obj), MappingUtils.buildOperationOptions( MappingUtils.getPullItems(provision.get().getMapping().getItems()).iterator())); @@ -211,20 +217,45 @@ public class PullUtils { break; case "username": - User user = userDAO.findByUsername(connObjectKey); - if (user != null) { - result.add(user.getKey()); + if (provision.getAnyType().getKind() == AnyTypeKind.USER && provision.isIgnoreCaseMatch()) { + AnyCond cond = new AnyCond(AttributeCond.Type.IEQ); + cond.setSchema("username"); + cond.setExpression(connObjectKey); + result.addAll(searchDAO.search(SearchCond.getLeafCond(cond), AnyTypeKind.USER). + stream().map(Entity::getKey).collect(Collectors.toList())); + } else { + User user = userDAO.findByUsername(connObjectKey); + if (user != null) { + result.add(user.getKey()); + } } break; case "name": - Group group = groupDAO.findByName(connObjectKey); - if (group != null) { - result.add(group.getKey()); + if (provision.getAnyType().getKind() == AnyTypeKind.GROUP && provision.isIgnoreCaseMatch()) { + AnyCond cond = new AnyCond(AttributeCond.Type.IEQ); + cond.setSchema("name"); + cond.setExpression(connObjectKey); + result.addAll(searchDAO.search(SearchCond.getLeafCond(cond), AnyTypeKind.GROUP). + stream().map(Entity::getKey).collect(Collectors.toList())); + } else { + Group group = groupDAO.findByName(connObjectKey); + if (group != null) { + result.add(group.getKey()); + } } - AnyObject anyObject = anyObjectDAO.findByName(connObjectKey); - if (anyObject != null) { - result.add(anyObject.getKey()); + + if (provision.getAnyType().getKind() == AnyTypeKind.ANY_OBJECT && provision.isIgnoreCaseMatch()) { + AnyCond cond = new AnyCond(AttributeCond.Type.IEQ); + cond.setSchema("name"); + cond.setExpression(connObjectKey); + result.addAll(searchDAO.search(SearchCond.getLeafCond(cond), AnyTypeKind.ANY_OBJECT). + stream().map(Entity::getKey).collect(Collectors.toList())); + } else { + AnyObject anyObject = anyObjectDAO.findByName(connObjectKey); + if (anyObject != null) { + result.add(anyObject.getKey()); + } } break; @@ -247,15 +278,15 @@ public class PullUtils { } } - result.addAll(anyUtils.dao(). - findByPlainAttrValue(intAttrName.getSchemaName(), value).stream(). - map(Entity::getKey).collect(Collectors.toList())); + result.addAll(anyUtils.dao().findByPlainAttrValue( + intAttrName.getSchemaName(), value, provision.isIgnoreCaseMatch()). + stream().map(Entity::getKey).collect(Collectors.toList())); break; case DERIVED: - result.addAll(anyUtils.dao(). - findByDerAttrValue(intAttrName.getSchemaName(), connObjectKey).stream(). - map(Entity::getKey).collect(Collectors.toList())); + result.addAll(anyUtils.dao().findByDerAttrValue( + intAttrName.getSchemaName(), connObjectKey, provision.isIgnoreCaseMatch()). + stream().map(Entity::getKey).collect(Collectors.toList())); break; default: @@ -325,7 +356,7 @@ public class PullUtils { String connObjectKey = null; Optional<? extends OrgUnitItem> connObjectKeyItem = orgUnit.getConnObjectKeyItem(); - if (connObjectKeyItem != null) { + if (connObjectKeyItem.isPresent()) { Attribute connObjectKeyAttr = connObj.getAttributeByName(connObjectKeyItem.get().getExtAttrName()); if (connObjectKeyAttr != null) { connObjectKey = AttributeUtil.getStringValue(connObjectKeyAttr); @@ -357,8 +388,15 @@ public class PullUtils { break; case "name": - result.addAll(realmDAO.findByName(connObjectKey).stream(). - map(Entity::getKey).collect(Collectors.toList())); + if (orgUnit.isIgnoreCaseMatch()) { + final String realmName = connObjectKey; + result.addAll(realmDAO.findAll().stream(). + filter(r -> r.getName().equalsIgnoreCase(realmName)). + map(Entity::getKey).collect(Collectors.toList())); + } else { + result.addAll(realmDAO.findByName(connObjectKey).stream(). + map(Entity::getKey).collect(Collectors.toList())); + } break; case "fullpath": http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java index 65151dc..d0d2b21 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java @@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.java.pushpull; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.apache.syncope.common.lib.collections.IteratorChain; @@ -166,8 +167,16 @@ public class SinglePullJobDelegate extends PullJobDelegate implements SyncopeSin handler, options); + Optional<? extends Provision> userProvision = provision.getResource().getProvision(anyTypeDAO.findUser()); + boolean userIgnoreCaseMatch = userProvision.isPresent() + ? userProvision.get().isIgnoreCaseMatch() + : false; + Optional<? extends Provision> groupProvision = provision.getResource().getProvision(anyTypeDAO.findGroup()); + boolean groupIgnoreCaseMatch = groupProvision.isPresent() + ? groupProvision.get().isIgnoreCaseMatch() + : false; try { - setGroupOwners(ghandler); + setGroupOwners(ghandler, userIgnoreCaseMatch, groupIgnoreCaseMatch); } catch (Exception e) { LOG.error("While setting group owners", e); } http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java index d3f763b..3393753 100644 --- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java +++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java @@ -155,13 +155,13 @@ public class SAML2UserManager { } } - result.addAll(userDAO.findByPlainAttrValue(intAttrName.getSchemaName(), value).stream(). - map(user -> user.getUsername()).collect(Collectors.toList())); + result.addAll(userDAO.findByPlainAttrValue(intAttrName.getSchemaName(), value, false).stream(). + map(User::getUsername).collect(Collectors.toList())); break; case DERIVED: - result.addAll(userDAO.findByDerAttrValue(intAttrName.getSchemaName(), transformed).stream(). - map(user -> user.getUsername()).collect(Collectors.toList())); + result.addAll(userDAO.findByDerAttrValue(intAttrName.getSchemaName(), transformed, false).stream(). + map(User::getUsername).collect(Collectors.toList())); break; default: http://git-wip-us.apache.org/repos/asf/syncope/blob/1a3a05e2/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 32fe251..f8213d0 100644 --- a/pom.xml +++ b/pom.xml @@ -356,7 +356,7 @@ under the License. <properties> <syncope.version>${project.version}</syncope.version> - <connid.version>1.4.3.0</connid.version> + <connid.version>1.4.4.0-SNAPSHOT</connid.version> <connid.soap.version>1.4.2-SNAPSHOT</connid.soap.version> <connid.rest.version>1.0.2</connid.rest.version> <connid.database.version>2.2.5</connid.database.version>
