Java tutorial
/* * 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.reference; 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.List; import java.util.Set; import javax.ws.rs.core.Response; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.Predicate; 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.mod.StatusMod; import org.apache.syncope.common.lib.mod.UserMod; 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.to.SyncPolicyTO; import org.apache.syncope.common.lib.to.SyncTaskTO; import org.apache.syncope.common.lib.to.TaskExecTO; 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.ConnConfProperty; import org.apache.syncope.common.lib.types.PropagationTaskExecStatus; import org.apache.syncope.common.lib.types.ResourceDeassociationActionType; import org.apache.syncope.common.lib.types.SyncPolicySpecItem; import org.apache.syncope.common.lib.types.TaskType; import org.apache.syncope.common.lib.wrap.ResourceKey; import org.apache.syncope.common.rest.api.CollectionWrapper; import org.apache.syncope.common.rest.api.service.TaskService; import org.apache.syncope.core.misc.security.Encryptor; import org.apache.syncope.core.provisioning.java.sync.DBPasswordSyncActions; import org.apache.syncope.core.provisioning.java.sync.LDAPPasswordSyncActions; 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); syncTask.getActionsClassNames().add(TestSyncActions.class.getName()); taskService.update(syncTask); } @Test public void getSyncActionsClasses() { List<String> actions = syncopeService.info().getSyncActions(); assertNotNull(actions); assertFalse(actions.isEmpty()); } @Test public void list() { PagedResult<SyncTaskTO> tasks = taskService.list(TaskType.SYNCHRONIZATION, SyncopeClient.getListQueryBuilder().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); UserTO userTemplate = new UserTO(); userTemplate.getResources().add(RESOURCE_NAME_WS2); MembershipTO membershipTO = new MembershipTO(); membershipTO.setRightKey(8L); userTemplate.getMemberships().add(membershipTO); 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()); assertNotNull(task); assertEquals(actual.getKey(), task.getKey()); assertEquals(actual.getJobClassName(), task.getJobClassName()); 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("type", "a type")); inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome")); inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org")); inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org")); inUserTO.getAuxClasses().add("csv"); inUserTO.getDerAttrs().add(attrTO("csvuserid", null)); inUserTO = createUser(inUserTO); assertNotNull(inUserTO); assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV)); // ----------------------------- try { int usersPre = userService.list(SyncopeClient.getAnyListQueryBuilder() .realm(SyncopeConstants.ROOT_REALM).page(1).size(1).build()).getTotalCount(); assertNotNull(usersPre); execProvisioningTask(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("test9@syncope.apache.org", userTO.getPlainAttrMap().get("email").getValues().get(0)); assertEquals("test9@syncope.apache.org", 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("type").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, CollectionUtils.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("type").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(SyncopeClient.getAnyListQueryBuilder() .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()); // SYNCOPE-317 execProvisioningTask(SYNC_TASK_ID, 50, false); final Set<Long> pushTaskIds = new HashSet<>(); pushTaskIds.add(25L); pushTaskIds.add(26L); execProvisioningTasks(pushTaskIds, 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() { TaskExecTO execution = execProvisioningTask(SYNC_TASK_ID, 50, true); assertEquals("Execution of task " + execution.getTask() + " failed with message " + execution.getMessage(), "SUCCESS", execution.getStatus()); } @Test public void reconcileFromDB() { // update sync task TaskExecTO execution = execProvisioningTask(7L, 50, false); assertNotNull(execution.getStatus()); assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful()); UserTO userTO = readUser("testuser1"); assertNotNull(userTO); assertEquals("reconciled@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0)); assertEquals("suspended", userTO.getStatus()); // enable user on external resource JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource); jdbcTemplate.execute("UPDATE TEST SET STATUS=TRUE"); // re-execute the same SyncTask: now user must be active execution = execProvisioningTask(7L, 50, false); assertNotNull(execution.getStatus()); assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful()); userTO = readUser("testuser1"); assertNotNull(userTO); assertEquals("active", userTO.getStatus()); } /** * Clean Syncope and LDAP resource status. */ private void ldapCleanup() { PagedResult<GroupTO> matchingGroups = groupService.search(SyncopeClient.getAnySearchQueryBuilder() .realm(SyncopeConstants.ROOT_REALM) .fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()) .build()); if (matchingGroups.getSize() > 0) { for (GroupTO group : matchingGroups.getResult()) { groupService.bulkDeassociation(group.getKey(), ResourceDeassociationActionType.UNLINK, CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)); groupService.delete(group.getKey()); } } PagedResult<UserTO> matchingUsers = userService.search(SyncopeClient.getAnySearchQueryBuilder() .realm(SyncopeConstants.ROOT_REALM) .fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()) .build()); if (matchingUsers.getSize() > 0) { for (UserTO user : matchingUsers.getResult()) { userService.bulkDeassociation(user.getKey(), ResourceDeassociationActionType.UNLINK, CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)); userService.delete(user.getKey()); } } } @Test public void reconcileFromLDAP() { // First of all, clear any potential conflict with existing user / group ldapCleanup(); // 0. synchronize TaskExecTO execution = execProvisioningTask(11L, 50, false); // 1. verify execution status String status = execution.getStatus(); assertNotNull(status); assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful()); // 2. verify that synchronized group is found, with expected attributes PagedResult<GroupTO> matchingGroups = groupService.search(SyncopeClient.getAnySearchQueryBuilder() .realm(SyncopeConstants.ROOT_REALM) .fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()) .build()); assertNotNull(matchingGroups); assertEquals(1, matchingGroups.getResult().size()); PagedResult<UserTO> matchingUsers = userService.search(SyncopeClient.getAnySearchQueryBuilder() .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()); } @Test public void reconcileFromScriptedSQL() { // 0. reset sync token ResourceTO resource = resourceService.read(RESOURCE_NAME_DBSCRIPTED); ProvisionTO provision = resource.getProvision("PRINTER"); assertNotNull(provision); provision.setSyncToken(null); resourceService.update(resource); // 1. create printer on external resource AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("sync"); anyObjectTO = createAnyObject(anyObjectTO); assertNotNull(anyObjectTO); // 2. unlink any existing printer and delete from Syncope (printer is now only on external resource) PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(SyncopeClient.getAnySearchQueryBuilder() .realm(SyncopeConstants.ROOT_REALM).fiql(SyncopeClient.getAnyObjectSearchConditionBuilder() .type("PRINTER").and().is("location").equalTo("sync*").query()) .build()); assertTrue(matchingPrinters.getSize() > 0); for (AnyObjectTO printer : matchingPrinters.getResult()) { anyObjectService.bulkDeassociation(printer.getKey(), ResourceDeassociationActionType.UNLINK, CollectionWrapper.wrap(RESOURCE_NAME_DBSCRIPTED, ResourceKey.class)); anyObjectService.delete(printer.getKey()); } // 3. synchronize execProvisioningTask(28L, 50, false); // 4. verify that printer was re-created in Syncope matchingPrinters = anyObjectService.search(SyncopeClient.getAnySearchQueryBuilder() .realm(SyncopeConstants.ROOT_REALM).fiql(SyncopeClient.getAnyObjectSearchConditionBuilder() .type("PRINTER").and().is("location").equalTo("sync*").query()) .build()); assertTrue(matchingPrinters.getSize() > 0); // 5. verify that synctoken was updated assertNotNull( resourceService.read(RESOURCE_NAME_DBSCRIPTED).getProvision(anyObjectTO.getType()).getSyncToken()); } @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("type", "a type")); userTO.getPlainAttrs().add(attrTO("fullname", "a type")); userTO.getPlainAttrs().add(attrTO("userId", "testuser2@syncope.apache.org")); userTO.getPlainAttrs().add(attrTO("email", "testuser2@syncope.apache.org")); userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2); userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4); MembershipTO membershipTO = new MembershipTO(); membershipTO.setRightKey(7L); userTO.getMemberships().add(membershipTO); userTO = createUser(userTO); assertNotNull(userTO); assertEquals("testuser2", userTO.getUsername()); assertEquals(1, userTO.getMemberships().size()); assertEquals(3, userTO.getResources().size()); //----------------------------- try { //----------------------------- // add user template //----------------------------- UserTO template = new UserTO(); membershipTO = new MembershipTO(); membershipTO.setRightKey(10L); template.getMemberships().add(membershipTO); template.getResources().add(RESOURCE_NAME_NOPROPAGATION4); //----------------------------- // Update sync task SyncTaskTO task = taskService.read(9L); assertNotNull(task); task.getTemplates().put(AnyTypeKind.USER.name(), template); taskService.update(task); SyncTaskTO actual = taskService.read(task.getKey()); 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()); TaskExecTO execution = execProvisioningTask(actual.getKey(), 50, false); final String status = execution.getStatus(); assertNotNull(status); assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful()); userTO = readUser("testuser2"); assertNotNull(userTO); assertEquals("testuser2@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0)); assertEquals(2, userTO.getMemberships().size()); assertEquals(4, userTO.getResources().size()); } finally { UserTO dUserTO = deleteUser(userTO.getKey()); assertNotNull(dUserTO); } } @Test public void issueSYNCOPE230() { // 1. read SyncTask for resource-db-sync (table TESTSYNC on external H2) execProvisioningTask(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='updatedSYNCOPE230@syncope.apache.org'"); // 5. re-execute the SyncTask execProvisioningTask(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("updatedSYNCOPE230@syncope.apache.org", email); } @Test public void issueSYNCOPE258() { // ----------------------------- // Add a custom correlation rule // ----------------------------- SyncPolicyTO policyTO = policyService.read(9L); SyncPolicySpecItem item = policyTO.getSpecification().getItem(AnyTypeKind.USER.name()); if (item == null) { item = new SyncPolicySpecItem(); item.setAnyTypeKey(AnyTypeKind.USER.name()); policyTO.getSpecification().getItems().add(item); } item.setJavaRule(TestSyncRule.class.getName()); policyService.update(policyTO); // ----------------------------- SyncTaskTO task = new SyncTaskTO(); task.setDestinationRealm(SyncopeConstants.ROOT_REALM); task.setName("Test Sync Rule"); task.setResource(RESOURCE_NAME_WS2); task.setFullReconciliation(true); task.setPerformCreate(true); task.setPerformDelete(true); task.setPerformUpdate(true); Response response = taskService.create(task); SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class); assertNotNull(actual); UserTO userTO = UserITCase.getUniqueSampleTO("s258_1@apache.org"); userTO.getResources().clear(); userTO.getResources().add(RESOURCE_NAME_WS2); createUser(userTO); userTO = UserITCase.getUniqueSampleTO("s258_2@apache.org"); userTO.getResources().clear(); userTO.getResources().add(RESOURCE_NAME_WS2); userTO = createUser(userTO); // change email in order to unmatch the second user UserMod userMod = new UserMod(); userMod.setKey(userTO.getKey()); userMod.getPlainAttrsToRemove().add("email"); userMod.getPlainAttrsToUpdate().add(attrMod("email", "s258@apache.org")); userService.update(userMod); execProvisioningTask(actual.getKey(), 50, false); SyncTaskTO executed = taskService.read(actual.getKey()); 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("syncope272@syncope.apache.org"); userTO.getResources().add(RESOURCE_NAME_TESTDB); userTO = createUser(userTO); try { assertNotNull(userTO); assertEquals(1, userTO.getPropagationStatusTOs().size()); assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful()); TaskExecTO taskExecTO = execProvisioningTask(24L, 50, false); assertNotNull(taskExecTO.getStatus()); assertTrue(PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()).isSuccessful()); 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("s307@apache.org"); 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.getResources().add(RESOURCE_NAME_CSV); userTO = createUser(userTO); assertNotNull(userTO); userTO = userService.read(userTO.getKey()); assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0)); // Update sync task SyncTaskTO task = taskService.read(12L); assertNotNull(task); // add user template UserTO template = new UserTO(); template.getResources().add(RESOURCE_NAME_DBVIRATTR); AttrTO userId = attrTO("userId", "'s307@apache.org'"); template.getPlainAttrs().add(userId); AttrTO email = attrTO("email", "'s307@apache.org'"); template.getPlainAttrs().add(email); task.getTemplates().put(AnyTypeKind.USER.name(), template); taskService.update(task); execProvisioningTask(task.getKey(), 50, false); // check for sync policy userTO = userService.read(userTO.getKey()); assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0)); try { final 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("syncope313-db@syncope.apache.org"); user.setPassword("security123"); user.getResources().add(RESOURCE_NAME_TESTDB); user = createUser(user); 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 newPassword = Encryptor.getInstance().encode("new-security", 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.setPerformCreate(true); syncTask.setPerformUpdate(true); syncTask.setFullReconciliation(true); 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()); assertNotNull(syncTask); assertEquals(actual.getKey(), syncTask.getKey()); assertEquals(actual.getJobClassName(), syncTask.getJobClassName()); TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false); final String status = execution.getStatus(); assertNotNull(status); assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful()); // 5. Test the sync'd user UserTO updatedUser = userService.read(user.getKey()); assertEquals(newPassword, updatedUser.getPassword()); // 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 UserTO user = UserITCase.getUniqueSampleTO("syncope313-ldap@syncope.apache.org"); user.setPassword("security123"); user.getResources().add(RESOURCE_NAME_LDAP); user = createUser(user); assertNotNull(user); assertFalse(user.getResources().isEmpty()); // 2. request to change password only on Syncope and not on LDAP UserMod userMod = new UserMod(); userMod.setKey(user.getKey()); userMod.setPassword("new-security123"); StatusMod pwdPropRequest = new StatusMod(); pwdPropRequest.setOnSyncope(true); pwdPropRequest.getResourceNames().clear(); userMod.setPwdPropRequest(pwdPropRequest); updateUser(userMod); // 3. Check that the Syncope user now has the changed password UserTO updatedUser = userService.read(user.getKey()); String encodedNewPassword = Encryptor.getInstance().encode("new-security123", CipherAlgorithm.SHA1); assertEquals(encodedNewPassword, updatedUser.getPassword()); // 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), "security123", 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()); ConnConfProperty property = resourceConnector.getConfigurationMap().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.setPerformCreate(true); syncTask.setPerformUpdate(true); syncTask.setFullReconciliation(true); syncTask.setResource(RESOURCE_NAME_LDAP); syncTask.getActionsClassNames().add(LDAPPasswordSyncActions.class.getName()); Response taskResponse = taskService.create(syncTask); SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class); assertNotNull(actual); syncTask = taskService.read(actual.getKey()); assertNotNull(syncTask); assertEquals(actual.getKey(), syncTask.getKey()); assertEquals(actual.getJobClassName(), syncTask.getJobClassName()); TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false); String status = execution.getStatus(); assertNotNull(status); assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful()); // 7. Test the sync'd user String syncedPassword = Encryptor.getInstance().encode("security123", CipherAlgorithm.SHA1); updatedUser = userService.read(user.getKey()); assertEquals(syncedPassword, updatedUser.getPassword()); // 8. Delete SyncTask + user + reset the connector taskService.delete(syncTask.getKey()); property.getValues().clear(); property.getValues().add(Boolean.FALSE); connectorService.update(resourceConnector); deleteUser(updatedUser.getKey()); } }