[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>

Reply via email to