http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
new file mode 100644
index 0000000..dc3df18
--- /dev/null
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
@@ -0,0 +1,853 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.patch.DeassociationPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.policy.PullPolicyTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.to.ExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
+import org.apache.syncope.common.lib.types.PullMode;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+import org.apache.syncope.common.rest.api.beans.TaskQuery;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.core.spring.security.Encryptor;
+import 
org.apache.syncope.core.provisioning.java.pushpull.DBPasswordPullActions;
+import 
org.apache.syncope.core.provisioning.java.pushpull.LDAPPasswordPullActions;
+import org.apache.syncope.fit.ActivitiDetector;
+import org.apache.syncope.fit.core.reference.PrefixMappingItemTransformer;
+import org.apache.syncope.fit.core.reference.TestReconciliationFilterBuilder;
+import org.apache.syncope.fit.core.reference.TestPullActions;
+import org.apache.syncope.fit.core.reference.TestPullRule;
+import org.identityconnectors.framework.common.objects.Name;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PullTaskITCase extends AbstractTaskITCase {
+
+    @BeforeClass
+    public static void testPullctionsSetup() {
+        PullTaskTO pullTask = taskService.read(PULL_TASK_ID, true);
+        pullTask.getActionsClassNames().add(TestPullActions.class.getName());
+        taskService.update(pullTask);
+    }
+
+    @Test
+    public void getPullActionsClasses() {
+        Set<String> actions = syncopeService.platform().getPullActions();
+        assertNotNull(actions);
+        assertFalse(actions.isEmpty());
+    }
+
+    @Test
+    public void list() {
+        PagedResult<PullTaskTO> tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PULL).build());
+        assertFalse(tasks.getResult().isEmpty());
+        for (AbstractTaskTO task : tasks.getResult()) {
+            if (!(task instanceof PullTaskTO)) {
+                fail();
+            }
+        }
+    }
+
+    @Test
+    public void create() {
+        PullTaskTO task = new PullTaskTO();
+        task.setName("Test create Pull");
+        task.setDestinationRealm("/");
+        task.setResource(RESOURCE_NAME_WS2);
+        task.setPullMode(PullMode.FULL_RECONCILIATION);
+
+        UserTO userTemplate = new UserTO();
+        userTemplate.getResources().add(RESOURCE_NAME_WS2);
+
+        userTemplate.getMemberships().add(new 
MembershipTO.Builder().group(8L).build());
+        task.getTemplates().put(AnyTypeKind.USER.name(), userTemplate);
+
+        GroupTO groupTemplate = new GroupTO();
+        groupTemplate.getResources().add(RESOURCE_NAME_LDAP);
+        task.getTemplates().put(AnyTypeKind.GROUP.name(), groupTemplate);
+
+        Response response = taskService.create(task);
+        PullTaskTO actual = getObject(response.getLocation(), 
TaskService.class, PullTaskTO.class);
+        assertNotNull(actual);
+
+        task = taskService.read(actual.getKey(), true);
+        assertNotNull(task);
+        assertEquals(actual.getKey(), task.getKey());
+        assertEquals(actual.getJobDelegateClassName(), 
task.getJobDelegateClassName());
+        assertEquals(userTemplate, 
task.getTemplates().get(AnyTypeKind.USER.name()));
+        assertEquals(groupTemplate, 
task.getTemplates().get(AnyTypeKind.GROUP.name()));
+    }
+
+    @Test
+    public void pull() throws Exception {
+        removeTestUsers();
+
+        // -----------------------------
+        // Create a new user ... it should be updated applying pull policy
+        // -----------------------------
+        UserTO inUserTO = new UserTO();
+        inUserTO.setRealm(SyncopeConstants.ROOT_REALM);
+        inUserTO.setPassword("password123");
+        String userName = "test9";
+        inUserTO.setUsername(userName);
+        inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
+        inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
+        inUserTO.getPlainAttrs().add(attrTO("ctype", "a type"));
+        inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
+        inUserTO.getPlainAttrs().add(attrTO("userId", 
"[email protected]"));
+        inUserTO.getPlainAttrs().add(attrTO("email", 
"[email protected]"));
+        inUserTO.getAuxClasses().add("csv");
+        inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+        inUserTO = createUser(inUserTO).getAny();
+        assertNotNull(inUserTO);
+        assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
+
+        // -----------------------------
+        try {
+            int usersPre = userService.list(
+                    new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    page(1).size(1).build()).getTotalCount();
+            assertNotNull(usersPre);
+
+            execProvisioningTask(taskService, PULL_TASK_ID, 50, false);
+
+            // after execution of the pull task the user data should have been 
pulled from CSV
+            // and processed by user template
+            UserTO userTO = userService.read(inUserTO.getKey());
+            assertNotNull(userTO);
+            assertEquals(userName, userTO.getUsername());
+            
assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                    ? "active" : "created", userTO.getStatus());
+            assertEquals("[email protected]", 
userTO.getPlainAttrMap().get("email").getValues().get(0));
+            assertEquals("[email protected]", 
userTO.getPlainAttrMap().get("userId").getValues().get(0));
+            
assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0))
 <= 10);
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+
+            // Matching --> Update (no link)
+            assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
+
+            // check for user template
+            userTO = readUser("test7");
+            assertNotNull(userTO);
+            assertEquals("TYPE_OTHER", 
userTO.getPlainAttrMap().get("ctype").getValues().get(0));
+            assertEquals(3, userTO.getResources().size());
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+            assertEquals(1, userTO.getMemberships().size());
+            assertEquals(8, userTO.getMemberships().get(0).getRightKey());
+
+            // Unmatching --> Assign (link) - SYNCOPE-658
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
+            assertEquals(1, IterableUtils.countMatches(userTO.getDerAttrs(), 
new Predicate<AttrTO>() {
+
+                @Override
+                public boolean evaluate(final AttrTO attributeTO) {
+                    return "csvuserid".equals(attributeTO.getSchema());
+                }
+            }));
+
+            userTO = readUser("test8");
+            assertNotNull(userTO);
+            assertEquals("TYPE_8", 
userTO.getPlainAttrMap().get("ctype").getValues().get(0));
+
+            // Check for ignored user - SYNCOPE-663
+            try {
+                readUser("test2");
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(Response.Status.NOT_FOUND, 
e.getType().getResponseStatus());
+            }
+
+            // check for pull results
+            int usersPost = userService.list(
+                    new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    page(1).size(1).build()).getTotalCount();
+            assertNotNull(usersPost);
+            assertEquals(usersPre + 8, usersPost);
+
+            // Check for issue 215:
+            // * expected disabled user test1
+            // * expected enabled user test3
+            userTO = readUser("test1");
+            assertNotNull(userTO);
+            assertEquals("suspended", userTO.getStatus());
+
+            userTO = readUser("test3");
+            assertNotNull(userTO);
+            assertEquals("active", userTO.getStatus());
+
+            Set<Long> otherPullTaskKeys = new HashSet<>();
+            otherPullTaskKeys.add(25L);
+            otherPullTaskKeys.add(26L);
+            execProvisioningTasks(taskService, otherPullTaskKeys, 50, false);
+
+            // Matching --> UNLINK
+            
assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
+            
assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
+        } finally {
+            removeTestUsers();
+        }
+    }
+
+    @Test
+    public void dryRun() {
+        ExecTO execution = execProvisioningTask(taskService, PULL_TASK_ID, 50, 
true);
+        assertEquals(
+                "Execution of " + execution.getRefDesc() + " failed with 
message " + execution.getMessage(),
+                "SUCCESS", execution.getStatus());
+    }
+
+    @Test
+    public void reconcileFromDB() {
+        UserTO userTO = null;
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        try {
+            ExecTO execution = execProvisioningTask(taskService, 7L, 50, 
false);
+            assertNotNull(execution.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            userTO = readUser("testuser1");
+            assertNotNull(userTO);
+            assertEquals("[email protected]", 
userTO.getPlainAttrMap().get("userId").getValues().get(0));
+            assertEquals("suspended", userTO.getStatus());
+
+            // enable user on external resource
+            jdbcTemplate.execute("UPDATE TEST SET status=TRUE WHERE 
id='testuser1'");
+
+            // re-execute the same PullTask: now user must be active
+            execution = execProvisioningTask(taskService, 7L, 50, false);
+            assertNotNull(execution.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            userTO = readUser("testuser1");
+            assertNotNull(userTO);
+            assertEquals("active", userTO.getStatus());
+        } finally {
+            jdbcTemplate.execute("UPDATE TEST SET status=FALSE WHERE 
id='testUser1'");
+            if (userTO != null) {
+                userService.delete(userTO.getKey());
+            }
+        }
+    }
+
+    /**
+     * Clean Syncope and LDAP resource status.
+     */
+    private void ldapCleanup() {
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
+                build());
+        if (matchingGroups.getSize() > 0) {
+            for (GroupTO group : matchingGroups.getResult()) {
+                DeassociationPatch deassociationPatch = new 
DeassociationPatch();
+                deassociationPatch.setKey(group.getKey());
+                
deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+                groupService.deassociate(deassociationPatch);
+                groupService.delete(group.getKey());
+            }
+        }
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("pullFromLDAP").query()).
+                build());
+        if (matchingUsers.getSize() > 0) {
+            for (UserTO user : matchingUsers.getResult()) {
+                DeassociationPatch deassociationPatch = new 
DeassociationPatch();
+                deassociationPatch.setKey(user.getKey());
+                
deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+                userService.deassociate(deassociationPatch);
+                userService.delete(user.getKey());
+            }
+        }
+    }
+
+    @Test
+    public void reconcileFromLDAP() {
+        // First of all, clear any potential conflict with existing user / 
group
+        ldapCleanup();
+
+        // 0. pull
+        ExecTO execution = execProvisioningTask(taskService, 11L, 50, false);
+
+        // 1. verify execution status
+        assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+        // 2. verify that pulled group is found
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
+                build());
+        assertNotNull(matchingGroups);
+        assertEquals(1, matchingGroups.getResult().size());
+
+        // 3. verify that pulled user is found
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("pullFromLDAP").query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.getResult().size());
+
+        // Check for SYNCOPE-436
+        assertEquals("pullFromLDAP",
+                
matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
+        // Check for SYNCOPE-270
+        
assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("obscure"));
+        // Check for SYNCOPE-123
+        
assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
+
+        GroupTO groupTO = matchingGroups.getResult().iterator().next();
+        assertNotNull(groupTO);
+        assertEquals("testLDAPGroup", groupTO.getName());
+        assertEquals("true", 
groupTO.getPlainAttrMap().get("show").getValues().get(0));
+        assertEquals(matchingUsers.getResult().iterator().next().getKey(), 
groupTO.getUserOwner(), 0);
+        assertNull(groupTO.getGroupOwner());
+
+        // SYNCOPE-317
+        execProvisioningTask(taskService, 11L, 50, false);
+    }
+
+    @Test
+    public void reconcileFromScriptedSQL() {
+        // 0. reset sync token and set MappingItemTransformer
+        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
+        ResourceTO originalResource = SerializationUtils.clone(resource);
+        ProvisionTO provision = resource.getProvision("PRINTER");
+        assertNotNull(provision);
+
+        try {
+            provision.setSyncToken(null);
+
+            MappingItemTO mappingItem = IterableUtils.find(
+                    provision.getMapping().getItems(), new 
Predicate<MappingItemTO>() {
+
+                @Override
+                public boolean evaluate(final MappingItemTO object) {
+                    return "location".equals(object.getIntAttrName());
+                }
+            });
+            assertNotNull(mappingItem);
+            mappingItem.getMappingItemTransformerClassNames().clear();
+            
mappingItem.getMappingItemTransformerClassNames().add(PrefixMappingItemTransformer.class.getName());
+
+            resourceService.update(resource);
+
+            // 1. create printer on external resource
+            AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("pull");
+            String originalLocation = 
anyObjectTO.getPlainAttrMap().get("location").getValues().get(0);
+            
assertFalse(originalLocation.startsWith(PrefixMappingItemTransformer.PREFIX));
+
+            anyObjectTO = createAnyObject(anyObjectTO).getAny();
+            assertNotNull(anyObjectTO);
+
+            // 2. verify that PrefixMappingItemTransformer was applied during 
propagation
+            // (location starts with given prefix on external resource)
+            ConnObjectTO connObjectTO = resourceService.
+                    readConnObject(RESOURCE_NAME_DBSCRIPTED, 
anyObjectTO.getType(), anyObjectTO.getKey());
+            
assertFalse(anyObjectTO.getPlainAttrMap().get("location").getValues().get(0).
+                    startsWith(PrefixMappingItemTransformer.PREFIX));
+            
assertTrue(connObjectTO.getPlainAttrMap().get("LOCATION").getValues().get(0).
+                    startsWith(PrefixMappingItemTransformer.PREFIX));
+
+            // 3. unlink any existing printer and delete from Syncope (printer 
is now only on external resource)
+            PagedResult<AnyObjectTO> matchingPrinters = 
anyObjectService.search(
+                    new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    
fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                            is("location").equalTo("pull*").query()).build());
+            assertTrue(matchingPrinters.getSize() > 0);
+            for (AnyObjectTO printer : matchingPrinters.getResult()) {
+                DeassociationPatch deassociationPatch = new 
DeassociationPatch();
+                deassociationPatch.setKey(printer.getKey());
+                
deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+                
deassociationPatch.getResources().add(RESOURCE_NAME_DBSCRIPTED);
+                anyObjectService.deassociate(deassociationPatch);
+                anyObjectService.delete(printer.getKey());
+            }
+
+            // 4. pull
+            execProvisioningTask(taskService, 28L, 50, false);
+
+            // 5. verify that printer was re-created in Syncope (implies that 
location does not start with given prefix,
+            // hence PrefixMappingItemTransformer was applied during pull)
+            matchingPrinters = anyObjectService.search(
+                    new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    
fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                            is("location").equalTo("pull*").query()).build());
+            assertTrue(matchingPrinters.getSize() > 0);
+
+            // 6. verify that synctoken was updated
+            assertNotNull(
+                    
resourceService.read(RESOURCE_NAME_DBSCRIPTED).getProvision(anyObjectTO.getType()).getSyncToken());
+        } finally {
+            resourceService.update(originalResource);
+        }
+    }
+
+    @Test
+    public void filteredReconciliation() {
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        PullTaskTO task = null;
+        UserTO userTO = null;
+        try {
+            // 1. create 2 users on testpull
+            jdbcTemplate.execute("INSERT INTO testpull VALUES (1001, 'user1', 
'Doe', '[email protected]')");
+            jdbcTemplate.execute("INSERT INTO testpull VALUES (1002, 'user2', 
'Rossi', '[email protected]')");
+
+            // 2. create new pull task for test-db, with reconciliation filter 
(surname 'Rossi') 
+            task = taskService.read(10L, true);
+            task.setPullMode(PullMode.FILTERED_RECONCILIATION);
+            
task.setReconciliationFilterBuilderClassName(TestReconciliationFilterBuilder.class.getName());
+            Response response = taskService.create(task);
+            task = getObject(response.getLocation(), TaskService.class, 
PullTaskTO.class);
+            assertNotNull(task);
+            assertEquals(
+                    TestReconciliationFilterBuilder.class.getName(),
+                    task.getReconciliationFilterBuilderClassName());
+
+            // 3. exec task
+            ExecTO execution = execProvisioningTask(taskService, 
task.getKey(), 50, false);
+            assertNotNull(execution.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            // 4. verify that only enabled user was pulled
+            userTO = readUser("user2");
+            assertNotNull(userTO);
+
+            try {
+                readUser("user1");
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.NotFound, e.getType());
+            }
+        } finally {
+            jdbcTemplate.execute("DELETE FROM testpull WHERE id = 1001");
+            jdbcTemplate.execute("DELETE FROM testpull WHERE id = 1002");
+            if (task != null && task.getKey() != 7L) {
+                taskService.delete(task.getKey());
+            }
+            if (userTO != null) {
+                userService.delete(userTO.getKey());
+            }
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE68() {
+        //-----------------------------
+        // Create a new user ... it should be updated applying pull policy
+        //-----------------------------
+        UserTO userTO = new UserTO();
+        userTO.setRealm(SyncopeConstants.ROOT_REALM);
+        userTO.setPassword("password123");
+        userTO.setUsername("testuser2");
+
+        userTO.getPlainAttrs().add(attrTO("firstname", "testuser2"));
+        userTO.getPlainAttrs().add(attrTO("surname", "testuser2"));
+        userTO.getPlainAttrs().add(attrTO("ctype", "a type"));
+        userTO.getPlainAttrs().add(attrTO("fullname", "a type"));
+        userTO.getPlainAttrs().add(attrTO("userId", 
"[email protected]"));
+        userTO.getPlainAttrs().add(attrTO("email", 
"[email protected]"));
+
+        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2);
+        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+
+        userTO.getMemberships().add(new 
MembershipTO.Builder().group(7L).build());
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertEquals("testuser2", userTO.getUsername());
+        assertEquals(1, userTO.getMemberships().size());
+        assertEquals(3, userTO.getResources().size());
+        //-----------------------------
+
+        try {
+            //-----------------------------
+            //  add user template
+            //-----------------------------
+            UserTO template = new UserTO();
+
+            template.getMemberships().add(new 
MembershipTO.Builder().group(10L).build());
+
+            template.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+            //-----------------------------
+
+            // Update pull task
+            PullTaskTO task = taskService.read(9L, true);
+            assertNotNull(task);
+
+            task.getTemplates().put(AnyTypeKind.USER.name(), template);
+
+            taskService.update(task);
+            PullTaskTO actual = taskService.read(task.getKey(), true);
+            assertNotNull(actual);
+            assertEquals(task.getKey(), actual.getKey());
+            
assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getResources().isEmpty());
+            assertFalse(((UserTO) 
actual.getTemplates().get(AnyTypeKind.USER.name())).getMemberships().isEmpty());
+
+            ExecTO execution = execProvisioningTask(taskService, 
actual.getKey(), 50, false);
+            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            userTO = readUser("testuser2");
+            assertNotNull(userTO);
+            assertEquals("[email protected]", 
userTO.getPlainAttrMap().get("userId").getValues().get(0));
+            assertEquals(2, userTO.getMemberships().size());
+            assertEquals(4, userTO.getResources().size());
+        } finally {
+            UserTO dUserTO = deleteUser(userTO.getKey()).getAny();
+            assertNotNull(dUserTO);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE230() {
+        // 1. read PullTask for resource-db-pull (table TESTPULL on external 
H2)
+        execProvisioningTask(taskService, 10L, 50, false);
+
+        // 3. read e-mail address for user created by the PullTask first 
execution
+        UserTO userTO = readUser("issuesyncope230");
+        assertNotNull(userTO);
+        String email = 
userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+        assertNotNull(email);
+
+        // 4. update TESTPULL on external H2 by changing e-mail address
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        jdbcTemplate.execute("UPDATE TESTPULL SET 
email='[email protected]'");
+
+        // 5. re-execute the PullTask
+        execProvisioningTask(taskService, 10L, 50, false);
+
+        // 6. verify that the e-mail was updated
+        userTO = readUser("issuesyncope230");
+        assertNotNull(userTO);
+        email = 
userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+        assertNotNull(email);
+        assertEquals("[email protected]", email);
+    }
+
+    @Test
+    public void issueSYNCOPE258() {
+        // -----------------------------
+        // Add a custom correlation rule
+        // -----------------------------
+        PullPolicyTO policyTO = policyService.read(9L);
+        
policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), 
TestPullRule.class.getName());
+        policyService.update(policyTO);
+        // -----------------------------
+
+        PullTaskTO task = new PullTaskTO();
+        task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        task.setName("Test Pull Rule");
+        task.setActive(true);
+        task.setResource(RESOURCE_NAME_WS2);
+        task.setPullMode(PullMode.FULL_RECONCILIATION);
+        task.setPerformCreate(true);
+        task.setPerformDelete(true);
+        task.setPerformUpdate(true);
+
+        Response response = taskService.create(task);
+        task = getObject(response.getLocation(), TaskService.class, 
PullTaskTO.class);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("[email protected]");
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        createUser(userTO);
+
+        userTO = UserITCase.getUniqueSampleTO("[email protected]");
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        userTO = createUser(userTO).getAny();
+
+        // change email in order to unmatch the second user
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getPlainAttrs().add(attrAddReplacePatch("email", 
"[email protected]"));
+
+        userService.update(userPatch);
+
+        execProvisioningTask(taskService, task.getKey(), 50, false);
+
+        PullTaskTO executed = taskService.read(task.getKey(), true);
+        assertEquals(1, executed.getExecutions().size());
+
+        // asser for just one match
+        assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 
55) + "...",
+                
executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 
1/0"));
+    }
+
+    @Test
+    public void issueSYNCOPE272() {
+        removeTestUsers();
+
+        // create user with testdb resource
+        UserTO userTO = 
UserITCase.getUniqueSampleTO("[email protected]");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        userTO = result.getAny();
+        try {
+            assertNotNull(userTO);
+            assertEquals(1, result.getPropagationStatuses().size());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, 
result.getPropagationStatuses().get(0).getStatus());
+
+            ExecTO taskExecTO = execProvisioningTask(taskService, 24L, 50, 
false);
+
+            assertNotNull(taskExecTO.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()));
+
+            userTO = userService.read(userTO.getKey());
+            assertNotNull(userTO);
+            
assertNotNull(userTO.getPlainAttrMap().get("firstname").getValues().get(0));
+        } finally {
+            removeTestUsers();
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE307() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("[email protected]");
+        userTO.setUsername("test0");
+        userTO.getPlainAttrMap().get("firstname").getValues().clear();
+        userTO.getPlainAttrMap().get("firstname").getValues().add("nome0");
+        userTO.getAuxClasses().add("csv");
+
+        AttrTO csvuserid = new AttrTO();
+        csvuserid.setSchema("csvuserid");
+        userTO.getDerAttrs().add(csvuserid);
+
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        userTO = userService.read(userTO.getKey());
+        assertTrue(userTO.getVirAttrMap().isEmpty());
+
+        // Update pull task
+        PullTaskTO task = taskService.read(12L, true);
+        assertNotNull(task);
+
+        UserTO template = new UserTO();
+        template.setPassword("'password123'");
+        template.getResources().add(RESOURCE_NAME_DBVIRATTR);
+        template.getVirAttrs().add(attrTO("virtualdata", "'virtualvalue'"));
+
+        task.getTemplates().put(AnyTypeKind.USER.name(), template);
+
+        taskService.update(task);
+
+        // exec task: one user from CSV will match the user created above and 
template will be applied
+        execProvisioningTask(taskService, task.getKey(), 50, false);
+
+        // check that template was successfully applied...
+        userTO = userService.read(userTO.getKey());
+        assertEquals("virtualvalue", 
userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        // ...and that propagation to db succeeded
+        try {
+            JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+            String value = jdbcTemplate.queryForObject(
+                    "SELECT USERNAME FROM testpull WHERE ID=?", String.class, 
userTO.getKey());
+            assertEquals("virtualvalue", value);
+        } catch (EmptyResultDataAccessException e) {
+            fail();
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE313DB() throws Exception {
+        // 1. create user in DB
+        UserTO user = 
UserITCase.getUniqueSampleTO("[email protected]");
+        user.setPassword("security123");
+        user.getResources().add(RESOURCE_NAME_TESTDB);
+        user = createUser(user).getAny();
+        assertNotNull(user);
+        assertFalse(user.getResources().isEmpty());
+
+        // 2. Check that the DB resource has the correct password
+        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        String value = jdbcTemplate.queryForObject(
+                "SELECT PASSWORD FROM test WHERE ID=?", String.class, 
user.getUsername());
+        assertEquals(Encryptor.getInstance().encode("security123", 
CipherAlgorithm.SHA1), value.toUpperCase());
+
+        // 3. Update the password in the DB
+        String newCleanPassword = "new-security";
+        String newPassword = Encryptor.getInstance().encode(newCleanPassword, 
CipherAlgorithm.SHA1);
+        jdbcTemplate.execute("UPDATE test set PASSWORD='" + newPassword + "' 
where ID='" + user.getUsername() + "'");
+
+        // 4. Pull the user from the resource
+        PullTaskTO pullTask = new PullTaskTO();
+        pullTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        pullTask.setName("DB Pull Task");
+        pullTask.setActive(true);
+        pullTask.setPerformCreate(true);
+        pullTask.setPerformUpdate(true);
+        pullTask.setPullMode(PullMode.FULL_RECONCILIATION);
+        pullTask.setResource(RESOURCE_NAME_TESTDB);
+        
pullTask.getActionsClassNames().add(DBPasswordPullActions.class.getName());
+        Response taskResponse = taskService.create(pullTask);
+
+        PullTaskTO actual = getObject(taskResponse.getLocation(), 
TaskService.class, PullTaskTO.class);
+        assertNotNull(actual);
+
+        pullTask = taskService.read(actual.getKey(), true);
+        assertNotNull(pullTask);
+        assertEquals(actual.getKey(), pullTask.getKey());
+        assertEquals(actual.getJobDelegateClassName(), 
pullTask.getJobDelegateClassName());
+
+        ExecTO execution = execProvisioningTask(taskService, 
pullTask.getKey(), 50, false);
+        assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+        // 5. Test the pulled user
+        Pair<Map<String, Set<String>>, UserTO> self = 
clientFactory.create(user.getUsername(), newCleanPassword).self();
+        assertNotNull(self);
+
+        // 6. Delete PullTask + user
+        taskService.delete(pullTask.getKey());
+        deleteUser(user.getKey());
+    }
+
+    @Test
+    public void issueSYNCOPE313LDAP() throws Exception {
+        // First of all, clear any potential conflict with existing user / 
group
+        ldapCleanup();
+
+        // 1. create user in LDAP
+        String oldCleanPassword = "security123";
+        UserTO user = 
UserITCase.getUniqueSampleTO("[email protected]");
+        user.setPassword(oldCleanPassword);
+        user.getResources().add(RESOURCE_NAME_LDAP);
+        user = createUser(user).getAny();
+        assertNotNull(user);
+        assertFalse(user.getResources().isEmpty());
+
+        // 2. request to change password only on Syncope and not on LDAP
+        String newCleanPassword = "new-security123";
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(user.getKey());
+        userPatch.setPassword(new 
PasswordPatch.Builder().value(newCleanPassword).build());
+        user = updateUser(userPatch).getAny();
+
+        // 3. Check that the Syncope user now has the changed password
+        Pair<Map<String, Set<String>>, UserTO> self = 
clientFactory.create(user.getUsername(), newCleanPassword).self();
+        assertNotNull(self);
+
+        // 4. Check that the LDAP resource has the old password
+        ConnObjectTO connObject =
+                resourceService.readConnObject(RESOURCE_NAME_LDAP, 
AnyTypeKind.USER.name(), user.getKey());
+        assertNotNull(getLdapRemoteObject(
+                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
+                oldCleanPassword,
+                
connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+        // 5. Update the LDAP Connector to retrieve passwords
+        ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
+        ConnInstanceTO resourceConnector = connectorService.read(
+                ldapResource.getConnector(), Locale.ENGLISH.getLanguage());
+        ConnConfProperty property = 
resourceConnector.getConfMap().get("retrievePasswordsWithSearch");
+        property.getValues().clear();
+        property.getValues().add(Boolean.TRUE);
+        connectorService.update(resourceConnector);
+
+        // 6. Pull the user from the resource
+        PullTaskTO pullTask = new PullTaskTO();
+        pullTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        pullTask.setName("LDAP Pull Task");
+        pullTask.setActive(true);
+        pullTask.setPerformCreate(true);
+        pullTask.setPerformUpdate(true);
+        pullTask.setPullMode(PullMode.FULL_RECONCILIATION);
+        pullTask.setResource(RESOURCE_NAME_LDAP);
+        
pullTask.getActionsClassNames().add(LDAPPasswordPullActions.class.getName());
+        Response taskResponse = taskService.create(pullTask);
+
+        pullTask = getObject(taskResponse.getLocation(), TaskService.class, 
PullTaskTO.class);
+        assertNotNull(pullTask);
+
+        ExecTO execution = execProvisioningTask(taskService, 
pullTask.getKey(), 50, false);
+        assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+        // 7. Test the pulled user
+        self = clientFactory.create(user.getUsername(), 
oldCleanPassword).self();
+        assertNotNull(self);
+
+        // 8. Delete PullTask + user + reset the connector
+        taskService.delete(pullTask.getKey());
+        property.getValues().clear();
+        property.getValues().add(Boolean.FALSE);
+        connectorService.update(resourceConnector);
+        deleteUser(user.getKey());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
index 9b5a7ed..56d8ec3 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
@@ -39,12 +39,6 @@ import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 @FixMethodOrder(MethodSorters.JVM)
 public class ReportTemplateITCase extends AbstractITCase {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
index cc6706f..b3010ff 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
@@ -214,7 +214,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setIntMappingType(IntMappingType.GroupKey);
         item.setExtAttrName("groupId");
         item.setConnObjectKey(true);
-        item.setPurpose(MappingPurpose.SYNCHRONIZATION);
+        item.setPurpose(MappingPurpose.PULL);
         mapping.setConnObjectKeyItem(item);
 
         Response response = resourceService.create(resourceTO);
@@ -225,7 +225,7 @@ public class ResourceITCase extends AbstractITCase {
         
assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
         
assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping());
         
assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems());
-        assertEquals(MappingPurpose.SYNCHRONIZATION,
+        assertEquals(MappingPurpose.PULL,
                 
actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getConnObjectKeyItem().getPurpose());
         assertEquals(MappingPurpose.PROPAGATION,
                 
actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
index cac3810..1b0825d 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.lib.types.TaskType;
@@ -66,7 +66,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
                 taskService.list(new 
TaskQuery.Builder().type(TaskType.SCHEDULED).build());
         assertFalse(tasks.getResult().isEmpty());
         for (AbstractTaskTO task : tasks.getResult()) {
-            if (!(task instanceof SchedTaskTO) || task instanceof SyncTaskTO 
|| task instanceof PushTaskTO) {
+            if (!(task instanceof SchedTaskTO) || task instanceof PullTaskTO 
|| task instanceof PushTaskTO) {
                 fail();
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
index d18c94b..0e6a991 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
@@ -24,7 +24,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.Collection;
-import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
@@ -223,7 +222,7 @@ public class SearchITCase extends AbstractITCase {
                 build());
         assertNotNull(matchingUsers);
         assertEquals(2, matchingUsers.getPage());
-        assertEquals(2, matchingUsers.getResult().size());
+        assertFalse(matchingUsers.getResult().isEmpty());
     }
 
     @Test
@@ -414,18 +413,23 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void issueSYNCOPE768() {
-        final List<UserTO> usersWithType = userService.search(
+        int usersWithNullable = userService.search(
                 new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("ctype").notNullValue().query()).build()).
-                getResult();
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("ctype").nullValue().query()).build()).
+                getTotalCount();
+        assertTrue(usersWithNullable > 0);
 
-        assertFalse(usersWithType.isEmpty());
+        int nonOrdered = userService.search(
+                new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").notNullValue().query()).build()).
+                getTotalCount();
+        assertTrue(nonOrdered > 0);
 
-        final PagedResult<UserTO> matchedUsers = userService.search(
+        int orderedByNullable = userService.search(
                 new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
                 
fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").notNullValue().query()).
-                
orderBy(SyncopeClient.getOrderByClauseBuilder().asc("ctype").build()).build());
-
-        assertTrue(matchedUsers.getResult().size() > usersWithType.size());
+                
orderBy(SyncopeClient.getOrderByClauseBuilder().asc("ctype").build()).build()).
+                getTotalCount();
+        assertEquals(nonOrdered, orderedByNullable);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
deleted file mode 100644
index 87bec8b..0000000
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.fit.core;
-
-import org.apache.syncope.fit.ActivitiDetector;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.patch.DeassociationPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AbstractTaskTO;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.policy.SyncPolicyTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
-import org.apache.syncope.common.lib.to.ExecTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
-import org.apache.syncope.common.lib.types.SyncMode;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
-import org.apache.syncope.common.rest.api.beans.TaskQuery;
-import org.apache.syncope.common.rest.api.service.TaskService;
-import org.apache.syncope.core.spring.security.Encryptor;
-import 
org.apache.syncope.core.provisioning.java.syncpull.DBPasswordSyncActions;
-import 
org.apache.syncope.core.provisioning.java.syncpull.LDAPPasswordSyncActions;
-import org.apache.syncope.fit.core.reference.PrefixMappingItemTransformer;
-import org.apache.syncope.fit.core.reference.TestReconciliationFilterBuilder;
-import org.apache.syncope.fit.core.reference.TestSyncActions;
-import org.apache.syncope.fit.core.reference.TestSyncRule;
-import org.identityconnectors.framework.common.objects.Name;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class SyncTaskITCase extends AbstractTaskITCase {
-
-    @BeforeClass
-    public static void testSyncActionsSetup() {
-        SyncTaskTO syncTask = taskService.read(SYNC_TASK_ID, true);
-        syncTask.getActionsClassNames().add(TestSyncActions.class.getName());
-        taskService.update(syncTask);
-    }
-
-    @Test
-    public void getSyncActionsClasses() {
-        Set<String> actions = syncopeService.platform().getSyncActions();
-        assertNotNull(actions);
-        assertFalse(actions.isEmpty());
-    }
-
-    @Test
-    public void list() {
-        PagedResult<SyncTaskTO> tasks = taskService.list(
-                new 
TaskQuery.Builder().type(TaskType.SYNCHRONIZATION).build());
-        assertFalse(tasks.getResult().isEmpty());
-        for (AbstractTaskTO task : tasks.getResult()) {
-            if (!(task instanceof SyncTaskTO)) {
-                fail();
-            }
-        }
-    }
-
-    @Test
-    public void create() {
-        SyncTaskTO task = new SyncTaskTO();
-        task.setName("Test create Sync");
-        task.setDestinationRealm("/");
-        task.setResource(RESOURCE_NAME_WS2);
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
-
-        UserTO userTemplate = new UserTO();
-        userTemplate.getResources().add(RESOURCE_NAME_WS2);
-
-        userTemplate.getMemberships().add(new 
MembershipTO.Builder().group(8L).build());
-        task.getTemplates().put(AnyTypeKind.USER.name(), userTemplate);
-
-        GroupTO groupTemplate = new GroupTO();
-        groupTemplate.getResources().add(RESOURCE_NAME_LDAP);
-        task.getTemplates().put(AnyTypeKind.GROUP.name(), groupTemplate);
-
-        Response response = taskService.create(task);
-        SyncTaskTO actual = getObject(response.getLocation(), 
TaskService.class, SyncTaskTO.class);
-        assertNotNull(actual);
-
-        task = taskService.read(actual.getKey(), true);
-        assertNotNull(task);
-        assertEquals(actual.getKey(), task.getKey());
-        assertEquals(actual.getJobDelegateClassName(), 
task.getJobDelegateClassName());
-        assertEquals(userTemplate, 
task.getTemplates().get(AnyTypeKind.USER.name()));
-        assertEquals(groupTemplate, 
task.getTemplates().get(AnyTypeKind.GROUP.name()));
-    }
-
-    @Test
-    public void sync() throws Exception {
-        removeTestUsers();
-
-        // -----------------------------
-        // Create a new user ... it should be updated applying sync policy
-        // -----------------------------
-        UserTO inUserTO = new UserTO();
-        inUserTO.setRealm(SyncopeConstants.ROOT_REALM);
-        inUserTO.setPassword("password123");
-        String userName = "test9";
-        inUserTO.setUsername(userName);
-        inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
-        inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
-        inUserTO.getPlainAttrs().add(attrTO("ctype", "a type"));
-        inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
-        inUserTO.getPlainAttrs().add(attrTO("userId", 
"[email protected]"));
-        inUserTO.getPlainAttrs().add(attrTO("email", 
"[email protected]"));
-        inUserTO.getAuxClasses().add("csv");
-        inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        inUserTO = createUser(inUserTO).getAny();
-        assertNotNull(inUserTO);
-        assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
-
-        // -----------------------------
-        try {
-            int usersPre = userService.list(
-                    new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    page(1).size(1).build()).getTotalCount();
-            assertNotNull(usersPre);
-
-            execProvisioningTask(taskService, SYNC_TASK_ID, 50, false);
-
-            // after execution of the sync task the user data should have been 
synced from CSV
-            // and processed by user template
-            UserTO userTO = userService.read(inUserTO.getKey());
-            assertNotNull(userTO);
-            assertEquals(userName, userTO.getUsername());
-            
assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
-                    ? "active" : "created", userTO.getStatus());
-            assertEquals("[email protected]", 
userTO.getPlainAttrMap().get("email").getValues().get(0));
-            assertEquals("[email protected]", 
userTO.getPlainAttrMap().get("userId").getValues().get(0));
-            
assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0))
 <= 10);
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
-
-            // Matching --> Update (no link)
-            assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
-
-            // check for user template
-            userTO = readUser("test7");
-            assertNotNull(userTO);
-            assertEquals("TYPE_OTHER", 
userTO.getPlainAttrMap().get("ctype").getValues().get(0));
-            assertEquals(3, userTO.getResources().size());
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
-            assertEquals(1, userTO.getMemberships().size());
-            assertEquals(8, userTO.getMemberships().get(0).getRightKey());
-
-            // Unmatching --> Assign (link) - SYNCOPE-658
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
-            assertEquals(1, IterableUtils.countMatches(userTO.getDerAttrs(), 
new Predicate<AttrTO>() {
-
-                @Override
-                public boolean evaluate(final AttrTO attributeTO) {
-                    return "csvuserid".equals(attributeTO.getSchema());
-                }
-            }));
-
-            userTO = readUser("test8");
-            assertNotNull(userTO);
-            assertEquals("TYPE_8", 
userTO.getPlainAttrMap().get("ctype").getValues().get(0));
-
-            // Check for ignored user - SYNCOPE-663
-            try {
-                readUser("test2");
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(Response.Status.NOT_FOUND, 
e.getType().getResponseStatus());
-            }
-
-            // check for sync results
-            int usersPost = userService.list(
-                    new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    page(1).size(1).build()).getTotalCount();
-            assertNotNull(usersPost);
-            assertEquals(usersPre + 8, usersPost);
-
-            // Check for issue 215:
-            // * expected disabled user test1
-            // * expected enabled user test2
-            userTO = readUser("test1");
-            assertNotNull(userTO);
-            assertEquals("suspended", userTO.getStatus());
-
-            userTO = readUser("test3");
-            assertNotNull(userTO);
-            assertEquals("active", userTO.getStatus());
-
-            Set<Long> otherSyncTaskKeys = new HashSet<>();
-            otherSyncTaskKeys.add(25L);
-            otherSyncTaskKeys.add(26L);
-            execProvisioningTasks(taskService, otherSyncTaskKeys, 50, false);
-
-            // Matching --> UNLINK
-            
assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
-            
assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
-        } finally {
-            removeTestUsers();
-        }
-    }
-
-    @Test
-    public void dryRun() {
-        ExecTO execution = execProvisioningTask(taskService, SYNC_TASK_ID, 50, 
true);
-        assertEquals(
-                "Execution of " + execution.getRefDesc() + " failed with 
message " + execution.getMessage(),
-                "SUCCESS", execution.getStatus());
-    }
-
-    @Test
-    public void reconcileFromDB() {
-        UserTO userTO = null;
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        try {
-            ExecTO execution = execProvisioningTask(taskService, 7L, 50, 
false);
-            assertNotNull(execution.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            userTO = readUser("testuser1");
-            assertNotNull(userTO);
-            assertEquals("[email protected]", 
userTO.getPlainAttrMap().get("userId").getValues().get(0));
-            assertEquals("suspended", userTO.getStatus());
-
-            // enable user on external resource
-            jdbcTemplate.execute("UPDATE TEST SET status=TRUE WHERE 
id='testuser1'");
-
-            // re-execute the same SyncTask: now user must be active
-            execution = execProvisioningTask(taskService, 7L, 50, false);
-            assertNotNull(execution.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            userTO = readUser("testuser1");
-            assertNotNull(userTO);
-            assertEquals("active", userTO.getStatus());
-        } finally {
-            jdbcTemplate.execute("UPDATE TEST SET status=FALSE WHERE 
id='testUser1'");
-            if (userTO != null) {
-                userService.delete(userTO.getKey());
-            }
-        }
-    }
-
-    /**
-     * Clean Syncope and LDAP resource status.
-     */
-    private void ldapCleanup() {
-        PagedResult<GroupTO> matchingGroups = groupService.search(
-                new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
-                build());
-        if (matchingGroups.getSize() > 0) {
-            for (GroupTO group : matchingGroups.getResult()) {
-                DeassociationPatch deassociationPatch = new 
DeassociationPatch();
-                deassociationPatch.setKey(group.getKey());
-                
deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-                groupService.deassociate(deassociationPatch);
-                groupService.delete(group.getKey());
-            }
-        }
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
-                build());
-        if (matchingUsers.getSize() > 0) {
-            for (UserTO user : matchingUsers.getResult()) {
-                DeassociationPatch deassociationPatch = new 
DeassociationPatch();
-                deassociationPatch.setKey(user.getKey());
-                
deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-                userService.deassociate(deassociationPatch);
-                userService.delete(user.getKey());
-            }
-        }
-    }
-
-    @Test
-    public void reconcileFromLDAP() {
-        // First of all, clear any potential conflict with existing user / 
group
-        ldapCleanup();
-
-        // 0. synchronize
-        ExecTO execution = execProvisioningTask(taskService, 11L, 50, false);
-
-        // 1. verify execution status
-        assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-        // 2. verify that synchronized group is found
-        PagedResult<GroupTO> matchingGroups = groupService.search(
-                new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
-                build());
-        assertNotNull(matchingGroups);
-        assertEquals(1, matchingGroups.getResult().size());
-
-        // 3. verify that synchronized user is found
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
-                build());
-        assertNotNull(matchingUsers);
-        assertEquals(1, matchingUsers.getResult().size());
-
-        // Check for SYNCOPE-436
-        assertEquals("syncFromLDAP",
-                
matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
-        // Check for SYNCOPE-270
-        
assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("obscure"));
-        // Check for SYNCOPE-123
-        
assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
-
-        GroupTO groupTO = matchingGroups.getResult().iterator().next();
-        assertNotNull(groupTO);
-        assertEquals("testLDAPGroup", groupTO.getName());
-        assertEquals("true", 
groupTO.getPlainAttrMap().get("show").getValues().get(0));
-        assertEquals(matchingUsers.getResult().iterator().next().getKey(), 
groupTO.getUserOwner(), 0);
-        assertNull(groupTO.getGroupOwner());
-
-        // SYNCOPE-317
-        execProvisioningTask(taskService, 11L, 50, false);
-    }
-
-    @Test
-    public void reconcileFromScriptedSQL() {
-        // 0. reset sync token and set MappingItemTransformer
-        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
-        ResourceTO originalResource = SerializationUtils.clone(resource);
-        ProvisionTO provision = resource.getProvision("PRINTER");
-        assertNotNull(provision);
-
-        try {
-            provision.setSyncToken(null);
-
-            MappingItemTO mappingItem = IterableUtils.find(
-                    provision.getMapping().getItems(), new 
Predicate<MappingItemTO>() {
-
-                @Override
-                public boolean evaluate(final MappingItemTO object) {
-                    return "location".equals(object.getIntAttrName());
-                }
-            });
-            assertNotNull(mappingItem);
-            mappingItem.getMappingItemTransformerClassNames().clear();
-            
mappingItem.getMappingItemTransformerClassNames().add(PrefixMappingItemTransformer.class.getName());
-
-            resourceService.update(resource);
-
-            // 1. create printer on external resource
-            AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("sync");
-            String originalLocation = 
anyObjectTO.getPlainAttrMap().get("location").getValues().get(0);
-            
assertFalse(originalLocation.startsWith(PrefixMappingItemTransformer.PREFIX));
-
-            anyObjectTO = createAnyObject(anyObjectTO).getAny();
-            assertNotNull(anyObjectTO);
-
-            // 2. verify that PrefixMappingItemTransformer was applied during 
propagation
-            // (location starts with given prefix on external resource)
-            ConnObjectTO connObjectTO = resourceService.
-                    readConnObject(RESOURCE_NAME_DBSCRIPTED, 
anyObjectTO.getType(), anyObjectTO.getKey());
-            
assertFalse(anyObjectTO.getPlainAttrMap().get("location").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
-            
assertTrue(connObjectTO.getPlainAttrMap().get("LOCATION").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
-
-            // 3. unlink any existing printer and delete from Syncope (printer 
is now only on external resource)
-            PagedResult<AnyObjectTO> matchingPrinters = 
anyObjectService.search(
-                    new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    
fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
-                            is("location").equalTo("sync*").query()).build());
-            assertTrue(matchingPrinters.getSize() > 0);
-            for (AnyObjectTO printer : matchingPrinters.getResult()) {
-                DeassociationPatch deassociationPatch = new 
DeassociationPatch();
-                deassociationPatch.setKey(printer.getKey());
-                
deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-                
deassociationPatch.getResources().add(RESOURCE_NAME_DBSCRIPTED);
-                anyObjectService.deassociate(deassociationPatch);
-                anyObjectService.delete(printer.getKey());
-            }
-
-            // 4. synchronize
-            execProvisioningTask(taskService, 28L, 50, false);
-
-            // 5. verify that printer was re-created in Syncope (implies that 
location does not start with given prefix,
-            // hence PrefixMappingItemTransformer was applied during sync)
-            matchingPrinters = anyObjectService.search(
-                    new 
AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    
fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
-                            is("location").equalTo("sync*").query()).build());
-            assertTrue(matchingPrinters.getSize() > 0);
-
-            // 6. verify that synctoken was updated
-            assertNotNull(
-                    
resourceService.read(RESOURCE_NAME_DBSCRIPTED).getProvision(anyObjectTO.getType()).getSyncToken());
-        } finally {
-            resourceService.update(originalResource);
-        }
-    }
-
-    @Test
-    public void filteredReconciliation() {
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        SyncTaskTO task = null;
-        UserTO userTO = null;
-        try {
-            // 1. create 2 users on testsync
-            jdbcTemplate.execute("INSERT INTO testsync VALUES (1001, 'user1', 
'Doe', '[email protected]')");
-            jdbcTemplate.execute("INSERT INTO testsync VALUES (1002, 'user2', 
'Rossi', '[email protected]')");
-
-            // 2. create new sync task for test-db, with reconciliation filter 
(surname 'Rossi') 
-            task = taskService.read(10L, true);
-            task.setSyncMode(SyncMode.FILTERED_RECONCILIATION);
-            
task.setReconciliationFilterBuilderClassName(TestReconciliationFilterBuilder.class.getName());
-            Response response = taskService.create(task);
-            task = getObject(response.getLocation(), TaskService.class, 
SyncTaskTO.class);
-            assertNotNull(task);
-            assertEquals(
-                    TestReconciliationFilterBuilder.class.getName(),
-                    task.getReconciliationFilterBuilderClassName());
-
-            // 3. exec task
-            ExecTO execution = execProvisioningTask(taskService, 
task.getKey(), 50, false);
-            assertNotNull(execution.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            // 4. verify that only enabled user was synchronized
-            userTO = readUser("user2");
-            assertNotNull(userTO);
-
-            try {
-                readUser("user1");
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.NotFound, e.getType());
-            }
-        } finally {
-            jdbcTemplate.execute("DELETE FROM testsync WHERE id = 1001");
-            jdbcTemplate.execute("DELETE FROM testsync WHERE id = 1002");
-            if (task != null && task.getKey() != 7L) {
-                taskService.delete(task.getKey());
-            }
-            if (userTO != null) {
-                userService.delete(userTO.getKey());
-            }
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE68() {
-        //-----------------------------
-        // Create a new user ... it should be updated applying sync policy
-        //-----------------------------
-        UserTO userTO = new UserTO();
-        userTO.setRealm(SyncopeConstants.ROOT_REALM);
-        userTO.setPassword("password123");
-        userTO.setUsername("testuser2");
-
-        userTO.getPlainAttrs().add(attrTO("firstname", "testuser2"));
-        userTO.getPlainAttrs().add(attrTO("surname", "testuser2"));
-        userTO.getPlainAttrs().add(attrTO("ctype", "a type"));
-        userTO.getPlainAttrs().add(attrTO("fullname", "a type"));
-        userTO.getPlainAttrs().add(attrTO("userId", 
"[email protected]"));
-        userTO.getPlainAttrs().add(attrTO("email", 
"[email protected]"));
-
-        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2);
-        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
-
-        userTO.getMemberships().add(new 
MembershipTO.Builder().group(7L).build());
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertEquals("testuser2", userTO.getUsername());
-        assertEquals(1, userTO.getMemberships().size());
-        assertEquals(3, userTO.getResources().size());
-        //-----------------------------
-
-        try {
-            //-----------------------------
-            //  add user template
-            //-----------------------------
-            UserTO template = new UserTO();
-
-            template.getMemberships().add(new 
MembershipTO.Builder().group(10L).build());
-
-            template.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
-            //-----------------------------
-
-            // Update sync task
-            SyncTaskTO task = taskService.read(9L, true);
-            assertNotNull(task);
-
-            task.getTemplates().put(AnyTypeKind.USER.name(), template);
-
-            taskService.update(task);
-            SyncTaskTO actual = taskService.read(task.getKey(), true);
-            assertNotNull(actual);
-            assertEquals(task.getKey(), actual.getKey());
-            
assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getResources().isEmpty());
-            assertFalse(((UserTO) 
actual.getTemplates().get(AnyTypeKind.USER.name())).getMemberships().isEmpty());
-
-            ExecTO execution = execProvisioningTask(taskService, 
actual.getKey(), 50, false);
-            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            userTO = readUser("testuser2");
-            assertNotNull(userTO);
-            assertEquals("[email protected]", 
userTO.getPlainAttrMap().get("userId").getValues().get(0));
-            assertEquals(2, userTO.getMemberships().size());
-            assertEquals(4, userTO.getResources().size());
-        } finally {
-            UserTO dUserTO = deleteUser(userTO.getKey()).getAny();
-            assertNotNull(dUserTO);
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE230() {
-        // 1. read SyncTask for resource-db-sync (table TESTSYNC on external 
H2)
-        execProvisioningTask(taskService, 10L, 50, false);
-
-        // 3. read e-mail address for user created by the SyncTask first 
execution
-        UserTO userTO = readUser("issuesyncope230");
-        assertNotNull(userTO);
-        String email = 
userTO.getPlainAttrMap().get("email").getValues().iterator().next();
-        assertNotNull(email);
-
-        // 4. update TESTSYNC on external H2 by changing e-mail address
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        jdbcTemplate.execute("UPDATE TESTSYNC SET 
email='[email protected]'");
-
-        // 5. re-execute the SyncTask
-        execProvisioningTask(taskService, 10L, 50, false);
-
-        // 6. verify that the e-mail was updated
-        userTO = readUser("issuesyncope230");
-        assertNotNull(userTO);
-        email = 
userTO.getPlainAttrMap().get("email").getValues().iterator().next();
-        assertNotNull(email);
-        assertEquals("[email protected]", email);
-    }
-
-    @Test
-    public void issueSYNCOPE258() {
-        // -----------------------------
-        // Add a custom correlation rule
-        // -----------------------------
-        SyncPolicyTO policyTO = policyService.read(9L);
-        
policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), 
TestSyncRule.class.getName());
-        policyService.update(policyTO);
-        // -----------------------------
-
-        SyncTaskTO task = new SyncTaskTO();
-        task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        task.setName("Test Sync Rule");
-        task.setActive(true);
-        task.setResource(RESOURCE_NAME_WS2);
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        task.setPerformCreate(true);
-        task.setPerformDelete(true);
-        task.setPerformUpdate(true);
-
-        Response response = taskService.create(task);
-        task = getObject(response.getLocation(), TaskService.class, 
SyncTaskTO.class);
-
-        UserTO userTO = UserITCase.getUniqueSampleTO("[email protected]");
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        createUser(userTO);
-
-        userTO = UserITCase.getUniqueSampleTO("[email protected]");
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        userTO = createUser(userTO).getAny();
-
-        // change email in order to unmatch the second user
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getPlainAttrs().add(attrAddReplacePatch("email", 
"[email protected]"));
-
-        userService.update(userPatch);
-
-        execProvisioningTask(taskService, task.getKey(), 50, false);
-
-        SyncTaskTO executed = taskService.read(task.getKey(), true);
-        assertEquals(1, executed.getExecutions().size());
-
-        // asser for just one match
-        assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 
55) + "...",
-                
executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 
1/0"));
-    }
-
-    @Test
-    public void issueSYNCOPE272() {
-        removeTestUsers();
-
-        // create user with testdb resource
-        UserTO userTO = 
UserITCase.getUniqueSampleTO("[email protected]");
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        userTO = result.getAny();
-        try {
-            assertNotNull(userTO);
-            assertEquals(1, result.getPropagationStatuses().size());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, 
result.getPropagationStatuses().get(0).getStatus());
-
-            ExecTO taskExecTO = execProvisioningTask(taskService, 24L, 50, 
false);
-
-            assertNotNull(taskExecTO.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()));
-
-            userTO = userService.read(userTO.getKey());
-            assertNotNull(userTO);
-            
assertNotNull(userTO.getPlainAttrMap().get("firstname").getValues().get(0));
-        } finally {
-            removeTestUsers();
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE307() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("[email protected]");
-        userTO.setUsername("test0");
-        userTO.getPlainAttrMap().get("firstname").getValues().clear();
-        userTO.getPlainAttrMap().get("firstname").getValues().add("nome0");
-        userTO.getAuxClasses().add("csv");
-
-        AttrTO csvuserid = new AttrTO();
-        csvuserid.setSchema("csvuserid");
-        userTO.getDerAttrs().add(csvuserid);
-
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        userTO = userService.read(userTO.getKey());
-        assertTrue(userTO.getVirAttrMap().isEmpty());
-
-        // Update sync task
-        SyncTaskTO task = taskService.read(12L, true);
-        assertNotNull(task);
-
-        UserTO template = new UserTO();
-        template.setPassword("'password123'");
-        template.getResources().add(RESOURCE_NAME_DBVIRATTR);
-        template.getVirAttrs().add(attrTO("virtualdata", "'virtualvalue'"));
-
-        task.getTemplates().put(AnyTypeKind.USER.name(), template);
-
-        taskService.update(task);
-
-        // exec task: one user from CSV will match the user created above and 
template will be applied
-        execProvisioningTask(taskService, task.getKey(), 50, false);
-
-        // check that template was successfully applied...
-        userTO = userService.read(userTO.getKey());
-        assertEquals("virtualvalue", 
userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        // ...and that propagation to db succeeded
-        try {
-            JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-            String value = jdbcTemplate.queryForObject(
-                    "SELECT USERNAME FROM testsync WHERE ID=?", String.class, 
userTO.getKey());
-            assertEquals("virtualvalue", value);
-        } catch (EmptyResultDataAccessException e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE313DB() throws Exception {
-        // 1. create user in DB
-        UserTO user = 
UserITCase.getUniqueSampleTO("[email protected]");
-        user.setPassword("security123");
-        user.getResources().add(RESOURCE_NAME_TESTDB);
-        user = createUser(user).getAny();
-        assertNotNull(user);
-        assertFalse(user.getResources().isEmpty());
-
-        // 2. Check that the DB resource has the correct password
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        String value = jdbcTemplate.queryForObject(
-                "SELECT PASSWORD FROM test WHERE ID=?", String.class, 
user.getUsername());
-        assertEquals(Encryptor.getInstance().encode("security123", 
CipherAlgorithm.SHA1), value.toUpperCase());
-
-        // 3. Update the password in the DB
-        String newCleanPassword = "new-security";
-        String newPassword = Encryptor.getInstance().encode(newCleanPassword, 
CipherAlgorithm.SHA1);
-        jdbcTemplate.execute("UPDATE test set PASSWORD='" + newPassword + "' 
where ID='" + user.getUsername() + "'");
-
-        // 4. Sync the user from the resource
-        SyncTaskTO syncTask = new SyncTaskTO();
-        syncTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        syncTask.setName("DB Sync Task");
-        syncTask.setActive(true);
-        syncTask.setPerformCreate(true);
-        syncTask.setPerformUpdate(true);
-        syncTask.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        syncTask.setResource(RESOURCE_NAME_TESTDB);
-        
syncTask.getActionsClassNames().add(DBPasswordSyncActions.class.getName());
-        Response taskResponse = taskService.create(syncTask);
-
-        SyncTaskTO actual = getObject(taskResponse.getLocation(), 
TaskService.class, SyncTaskTO.class);
-        assertNotNull(actual);
-
-        syncTask = taskService.read(actual.getKey(), true);
-        assertNotNull(syncTask);
-        assertEquals(actual.getKey(), syncTask.getKey());
-        assertEquals(actual.getJobDelegateClassName(), 
syncTask.getJobDelegateClassName());
-
-        ExecTO execution = execProvisioningTask(taskService, 
syncTask.getKey(), 50, false);
-        assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-        // 5. Test the sync'd user
-        Pair<Map<String, Set<String>>, UserTO> self = 
clientFactory.create(user.getUsername(), newCleanPassword).self();
-        assertNotNull(self);
-
-        // 6. Delete SyncTask + user
-        taskService.delete(syncTask.getKey());
-        deleteUser(user.getKey());
-    }
-
-    @Test
-    public void issueSYNCOPE313LDAP() throws Exception {
-        // First of all, clear any potential conflict with existing user / 
group
-        ldapCleanup();
-
-        // 1. create user in LDAP
-        String oldCleanPassword = "security123";
-        UserTO user = 
UserITCase.getUniqueSampleTO("[email protected]");
-        user.setPassword(oldCleanPassword);
-        user.getResources().add(RESOURCE_NAME_LDAP);
-        user = createUser(user).getAny();
-        assertNotNull(user);
-        assertFalse(user.getResources().isEmpty());
-
-        // 2. request to change password only on Syncope and not on LDAP
-        String newCleanPassword = "new-security123";
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(user.getKey());
-        userPatch.setPassword(new 
PasswordPatch.Builder().value(newCleanPassword).build());
-        user = updateUser(userPatch).getAny();
-
-        // 3. Check that the Syncope user now has the changed password
-        Pair<Map<String, Set<String>>, UserTO> self = 
clientFactory.create(user.getUsername(), newCleanPassword).self();
-        assertNotNull(self);
-
-        // 4. Check that the LDAP resource has the old password
-        ConnObjectTO connObject =
-                resourceService.readConnObject(RESOURCE_NAME_LDAP, 
AnyTypeKind.USER.name(), user.getKey());
-        assertNotNull(getLdapRemoteObject(
-                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
-                oldCleanPassword,
-                
connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
-
-        // 5. Update the LDAP Connector to retrieve passwords
-        ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
-        ConnInstanceTO resourceConnector = connectorService.read(
-                ldapResource.getConnector(), Locale.ENGLISH.getLanguage());
-        ConnConfProperty property = 
resourceConnector.getConfMap().get("retrievePasswordsWithSearch");
-        property.getValues().clear();
-        property.getValues().add(Boolean.TRUE);
-        connectorService.update(resourceConnector);
-
-        // 6. Sync the user from the resource
-        SyncTaskTO syncTask = new SyncTaskTO();
-        syncTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        syncTask.setName("LDAP Sync Task");
-        syncTask.setActive(true);
-        syncTask.setPerformCreate(true);
-        syncTask.setPerformUpdate(true);
-        syncTask.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        syncTask.setResource(RESOURCE_NAME_LDAP);
-        
syncTask.getActionsClassNames().add(LDAPPasswordSyncActions.class.getName());
-        Response taskResponse = taskService.create(syncTask);
-
-        syncTask = getObject(taskResponse.getLocation(), TaskService.class, 
SyncTaskTO.class);
-        assertNotNull(syncTask);
-
-        ExecTO execution = execProvisioningTask(taskService, 
syncTask.getKey(), 50, false);
-        assertEquals(PropagationTaskExecStatus.SUCCESS, 
PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-        // 7. Test the sync'd user
-        self = clientFactory.create(user.getUsername(), 
oldCleanPassword).self();
-        assertNotNull(self);
-
-        // 8. Delete SyncTask + user + reset the connector
-        taskService.delete(syncTask.getKey());
-        property.getValues().clear();
-        property.getValues().add(Boolean.FALSE);
-        connectorService.update(resourceConnector);
-        deleteUser(user.getKey());
-    }
-}

Reply via email to