Author: ilgrosso Date: Wed Dec 4 15:34:14 2013 New Revision: 1547823 URL: http://svn.apache.org/r1547823 Log: [SYNCOPE-454] Merge from 1_1_X
Modified: syncope/trunk/ (props changed) syncope/trunk/console/pom.xml syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/EditUserModalPage.java syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Reports.java syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/StatusPanel.java syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java Propchange: syncope/trunk/ ------------------------------------------------------------------------------ Merged /syncope/branches/1_1_X:r1547767-1547809 Modified: syncope/trunk/console/pom.xml URL: http://svn.apache.org/viewvc/syncope/trunk/console/pom.xml?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/console/pom.xml (original) +++ syncope/trunk/console/pom.xml Wed Dec 4 15:34:14 2013 @@ -261,6 +261,7 @@ under the License. <fileset dir="${project.build.directory}/test-classes"> <exclude name="**/*.class"/> <exclude name="restClientContext.xml"/> + <exclude name="rest.properties"/> </fileset> </copy> </target> Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/EditUserModalPage.java URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/EditUserModalPage.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/EditUserModalPage.java (original) +++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/EditUserModalPage.java Wed Dec 4 15:34:14 2013 @@ -74,6 +74,7 @@ public class EditUserModalPage extends U } } + @SuppressWarnings("rawtypes") @Override protected void submitAction(final AjaxRequestTarget target, final Form form) { final UserTO updatedUserTO = (UserTO) form.getModelObject(); @@ -94,6 +95,7 @@ public class EditUserModalPage extends U } } + @SuppressWarnings("rawtypes") @Override protected void closeAction(final AjaxRequestTarget target, final Form form) { setResponsePage(new ResultStatusModalPage.Builder(window, userTO).mode(mode).build()); Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Reports.java URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Reports.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Reports.java (original) +++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Reports.java Wed Dec 4 15:34:14 2013 @@ -105,7 +105,7 @@ public class Reports extends BasePage { setupAudit(); } - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) private void setupReport() { reportContainer = new WebMarkupContainer("reportContainer"); setWindowClosedCallback(window, reportContainer); @@ -272,6 +272,7 @@ public class Reports extends BasePage { add(createLink); } + @SuppressWarnings("rawtypes") private void setupAudit() { auditContainer = new WebMarkupContainer("auditContainer"); auditContainer.setOutputMarkupId(true); @@ -300,77 +301,79 @@ public class Reports extends BasePage { form.add(new LoggerCategoryPanel( "events", loggerRestClient.listEvents(), model, getPageReference(), "Reports") { - private static final long serialVersionUID = 6113164334533550277L; + private static final long serialVersionUID = 6113164334533550277L; - @Override - protected String[] getListRoles() { - return new String[] { - xmlRolesReader.getAllAllowedRoles("Audit", "list") - }; - } + @Override + protected String[] getListRoles() { + return new String[] { + xmlRolesReader.getAllAllowedRoles("Audit", "list") + }; + } - @Override - protected String[] getChangeRoles() { - return new String[] { - xmlRolesReader.getAllAllowedRoles("Audit", "enable"), - xmlRolesReader.getAllAllowedRoles("Audit", "disable") - }; - } + @Override + protected String[] getChangeRoles() { + return new String[] { + xmlRolesReader.getAllAllowedRoles("Audit", "enable"), + xmlRolesReader.getAllAllowedRoles("Audit", "disable") + }; + } - @Override - public void onEventAction(final IEvent<?> event) { - if (event.getPayload() instanceof SelectedEventsPanel.EventSelectionChanged) { + @Override + public void onEventAction(final IEvent<?> event) { + if (event.getPayload() instanceof SelectedEventsPanel.EventSelectionChanged) { - final SelectedEventsPanel.EventSelectionChanged eventSelectionChanged = + final SelectedEventsPanel.EventSelectionChanged eventSelectionChanged = (SelectedEventsPanel.EventSelectionChanged) event.getPayload(); - for (String toBeRemoved : eventSelectionChanged.getToBeRemoved()) { - if (events.contains(toBeRemoved)) { - final Map.Entry<EventCategoryTO, Result> eventCategory = + for (String toBeRemoved : eventSelectionChanged.getToBeRemoved()) { + if (events.contains(toBeRemoved)) { + final Map.Entry<EventCategoryTO, Result> eventCategory = LoggerEventUtils.parseEventCategory(toBeRemoved); - final AuditLoggerName auditLoggerName = new AuditLoggerName( - eventCategory.getKey().getType(), - eventCategory.getKey().getCategory(), - eventCategory.getKey().getSubcategory(), - CollectionUtils.isEmpty(eventCategory.getKey().getEvents()) - ? null : eventCategory.getKey().getEvents().iterator().next(), - eventCategory.getValue()); - - loggerRestClient.disableAudit(auditLoggerName); - events.remove(toBeRemoved); - } - } + final AuditLoggerName auditLoggerName = new AuditLoggerName( + eventCategory.getKey().getType(), + eventCategory.getKey().getCategory(), + eventCategory.getKey().getSubcategory(), + CollectionUtils.isEmpty(eventCategory.getKey().getEvents()) + ? null : eventCategory.getKey().getEvents().iterator().next(), + eventCategory.getValue()); + + loggerRestClient.disableAudit(auditLoggerName); + events.remove(toBeRemoved); + } + } - for (String toBeAdded : eventSelectionChanged.getToBeAdded()) { - if (!events.contains(toBeAdded)) { - final Map.Entry<EventCategoryTO, Result> eventCategory = + for (String toBeAdded : eventSelectionChanged.getToBeAdded()) { + if (!events.contains(toBeAdded)) { + final Map.Entry<EventCategoryTO, Result> eventCategory = LoggerEventUtils.parseEventCategory(toBeAdded); - final AuditLoggerName auditLoggerName = new AuditLoggerName( - eventCategory.getKey().getType(), - eventCategory.getKey().getCategory(), - eventCategory.getKey().getSubcategory(), - CollectionUtils.isEmpty(eventCategory.getKey().getEvents()) - ? null : eventCategory.getKey().getEvents().iterator().next(), - eventCategory.getValue()); - - loggerRestClient.enableAudit(auditLoggerName); - events.add(toBeAdded); + final AuditLoggerName auditLoggerName = new AuditLoggerName( + eventCategory.getKey().getType(), + eventCategory.getKey().getCategory(), + eventCategory.getKey().getSubcategory(), + CollectionUtils.isEmpty(eventCategory.getKey().getEvents()) + ? null : eventCategory.getKey().getEvents().iterator().next(), + eventCategory.getValue()); + + loggerRestClient.enableAudit(auditLoggerName); + events.add(toBeAdded); + } + } } } - } - } - }); + }); } private class ReportProvider extends SortableDataProvider<ReportTO, String> { private static final long serialVersionUID = -2311716167583335852L; - private SortableDataProviderComparator<ReportTO> comparator; + private final SortableDataProviderComparator<ReportTO> comparator; public ReportProvider() { + super(); + //Default sorting setSort("id", SortOrder.ASCENDING); comparator = new SortableDataProviderComparator<ReportTO>(this); Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/StatusPanel.java URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/StatusPanel.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/StatusPanel.java (original) +++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/StatusPanel.java Wed Dec 4 15:34:14 2013 @@ -228,12 +228,11 @@ public class StatusPanel extends Panel i } public StatusMod getStatusMod() { - StatusMod result = null; + StatusMod result = new StatusMod(); Collection<StatusBean> statusBeans = checkGroup.getModel().getObject(); if (statusBeans != null && !statusBeans.isEmpty()) { result = StatusUtils.buildStatusMod(statusBeans); - } return result; Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java Wed Dec 4 15:34:14 2013 @@ -59,6 +59,7 @@ import org.apache.syncope.core.workflow. import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributeBuilder; import org.identityconnectors.framework.common.objects.AttributeUtil; +import org.identityconnectors.framework.common.objects.OperationalAttributes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -67,7 +68,7 @@ import org.springframework.transaction.a /** * Manage the data propagation to external resources. */ -@Transactional(rollbackFor = {Throwable.class}) +@Transactional(rollbackFor = { Throwable.class }) public class PropagationManager { /** @@ -198,7 +199,7 @@ public class PropagationManager { propByRes.get(ResourceOperation.CREATE).removeAll(noPropResourceNames); } - return createTasks(attributable, password, null, null, enable, false, propByRes); + return createTasks(attributable, password, true, null, null, enable, false, propByRes); } /** @@ -217,6 +218,7 @@ public class PropagationManager { return getUpdateTaskIds( user, // SyncopeUser to be updated on external resources null, // no password + false, enable, // status to be propagated Collections.<String>emptySet(), // no virtual attributes to be managed Collections.<AttributeMod>emptySet(), // no virtual attributes to be managed @@ -228,18 +230,20 @@ public class PropagationManager { * Performs update on each resource associated to the user. * * @param wfResult user to be propagated (and info associated), as per result from workflow + * @param changePwd whether password should be included for propagation attributes or not * @param noPropResourceNames external resources not to be considered for propagation * @return list of propagation tasks * @throws NotFoundException if user is not found * @throws UnauthorizedRoleException if caller doesn't own enough entitlements to administer the given user */ public List<PropagationTask> getUserUpdateTaskIds(final WorkflowResult<Map.Entry<UserMod, Boolean>> wfResult, - final Collection<String> noPropResourceNames) + final boolean changePwd, final Collection<String> noPropResourceNames) throws NotFoundException, UnauthorizedRoleException { SyncopeUser user = userDataBinder.getUserFromId(wfResult.getResult().getKey().getId()); return getUpdateTaskIds(user, wfResult.getResult().getKey().getPassword(), + changePwd, wfResult.getResult().getValue(), wfResult.getResult().getKey().getVirAttrsToRemove(), wfResult.getResult().getKey().getVirAttrsToUpdate(), @@ -254,7 +258,7 @@ public class PropagationManager { List<PropagationTask> tasks = new ArrayList<PropagationTask>(); if (userMod.getPwdPropRequest() == null) { // a. no specific password propagation request: generate propagation tasks for any resource associated - tasks = getUserUpdateTaskIds(wfResult, null); + tasks = getUserUpdateTaskIds(wfResult, true, null); } else { // b. generate the propagation task list in two phases: first the ones containing password, // the the rest (with no password) @@ -270,7 +274,7 @@ public class PropagationManager { Set<String> toBeExcluded = new HashSet<String>(currentResourceNames); toBeExcluded.addAll(userMod.getResourcesToAdd()); toBeExcluded.removeAll(pwdResourceNames); - tasks.addAll(getUserUpdateTaskIds(wfResult, toBeExcluded)); + tasks.addAll(getUserUpdateTaskIds(wfResult, true, toBeExcluded)); } final PropagationByResource nonPwdPropByRes = new PropagationByResource(); @@ -278,7 +282,7 @@ public class PropagationManager { nonPwdPropByRes.removeAll(pwdResourceNames); nonPwdPropByRes.purge(); if (!nonPwdPropByRes.isEmpty()) { - tasks.addAll(getUserUpdateTaskIds(wfResult, pwdResourceNames)); + tasks.addAll(getUserUpdateTaskIds(wfResult, false, pwdResourceNames)); } } @@ -319,12 +323,12 @@ public class PropagationManager { throws NotFoundException, UnauthorizedRoleException { SyncopeRole role = roleDataBinder.getRoleFromId(wfResult.getResult()); - return getUpdateTaskIds(role, null, null, + return getUpdateTaskIds(role, null, false, null, vAttrsToBeRemoved, vAttrsToBeUpdated, wfResult.getPropByRes(), noPropResourceNames); } protected List<PropagationTask> getUpdateTaskIds(final AbstractAttributable attributable, - final String password, final Boolean enable, + final String password, final boolean changePwd, final Boolean enable, final Set<String> vAttrsToBeRemoved, final Set<AttributeMod> vAttrsToBeUpdated, final PropagationByResource propByRes, final Collection<String> noPropResourceNames) throws NotFoundException { @@ -356,7 +360,7 @@ public class PropagationManager { } } - return createTasks(attributable, password, + return createTasks(attributable, password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdatedMap, enable, false, localPropByRes); } @@ -422,7 +426,7 @@ public class PropagationManager { */ public List<PropagationTask> getUserDeleteTaskIds(final WorkflowResult<Long> wfResult) { SyncopeUser user = userDataBinder.getUserFromId(wfResult.getResult()); - return createTasks(user, null, null, null, false, true, wfResult.getPropByRes()); + return createTasks(user, null, false, null, null, false, true, wfResult.getPropByRes()); } /** @@ -484,7 +488,7 @@ public class PropagationManager { if (noPropResourceNames != null && !noPropResourceNames.isEmpty()) { propByRes.get(ResourceOperation.DELETE).removeAll(noPropResourceNames); } - return createTasks(attributable, null, null, null, false, true, propByRes); + return createTasks(attributable, null, false, null, null, false, true, propByRes); } /** @@ -494,6 +498,7 @@ public class PropagationManager { * @param attrUtil user / role * @param subject given user / role * @param password clear-text password + * @param changePwd whether password should be included for propagation attributes or not * @param vAttrsToBeRemoved virtual attributes to be removed * @param vAttrsToBeUpdated virtual attributes to be added * @param enable whether user must be enabled or not @@ -501,7 +506,7 @@ public class PropagationManager { * @return account link + prepared attributes */ protected <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> prepareAttributes( - final AttributableUtil attrUtil, final T subject, final String password, + final AttributableUtil attrUtil, final T subject, final String password, final boolean changePwd, final Set<String> vAttrsToBeRemoved, final Map<String, AttributeMod> vAttrsToBeUpdated, final Boolean enable, final ExternalResource resource) { @@ -527,11 +532,11 @@ public class PropagationManager { Map.Entry<String, Attribute> preparedAttribute = MappingUtil.prepareAttribute( resource, mapping, subject, password, passwordGenerator, vAttrsToBeRemoved, vAttrsToBeUpdated); - if (preparedAttribute.getKey() != null) { + if (preparedAttribute != null && preparedAttribute.getKey() != null) { accountId = preparedAttribute.getKey(); } - if (preparedAttribute.getValue() != null) { + if (preparedAttribute != null && preparedAttribute.getValue() != null) { Attribute alreadyAdded = AttributeUtil.find(preparedAttribute.getValue().getName(), attributes); if (alreadyAdded == null) { @@ -555,6 +560,12 @@ public class PropagationManager { if (enable != null) { attributes.add(AttributeBuilder.buildEnabled(enable)); } + if (!changePwd) { + Attribute pwdAttr = AttributeUtil.find(OperationalAttributes.PASSWORD_NAME, attributes); + if (pwdAttr != null) { + attributes.remove(pwdAttr); + } + } return new SimpleEntry<String, Set<Attribute>>(accountId, attributes); } @@ -565,6 +576,7 @@ public class PropagationManager { * @param <T> user / role * @param subject user / role to be provisioned * @param password cleartext password to be provisioned + * @param changePwd whether password should be included for propagation attributes or not * @param vAttrsToBeRemoved virtual attributes to be removed * @param vAttrsToBeUpdated virtual attributes to be added * @param enable whether user must be enabled or not @@ -572,7 +584,8 @@ public class PropagationManager { * @param propByRes operation to be performed per resource * @return list of propagation tasks created */ - protected <T extends AbstractAttributable> List<PropagationTask> createTasks(final T subject, final String password, + protected <T extends AbstractAttributable> List<PropagationTask> createTasks(final T subject, + final String password, final boolean changePwd, final Set<String> vAttrsToBeRemoved, final Map<String, AttributeMod> vAttrsToBeUpdated, final Boolean enable, final boolean deleteOnResource, final PropagationByResource propByRes) { @@ -624,8 +637,8 @@ public class PropagationManager { task.setPropagationMode(resource.getPropagationMode()); task.setOldAccountId(propByRes.getOldAccountId(resource.getName())); - Map.Entry<String, Set<Attribute>> preparedAttrs = prepareAttributes(attrUtil, subject, password, - vAttrsToBeRemoved, vAttrsToBeUpdated, enable, resource); + Map.Entry<String, Set<Attribute>> preparedAttrs = prepareAttributes(attrUtil, subject, + password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdated, enable, resource); task.setAccountId(preparedAttrs.getKey()); // Check if any of mandatory attributes (in the mapping) is missing or not received any value: Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java Wed Dec 4 15:34:14 2013 @@ -174,7 +174,7 @@ public class RoleController extends Abst } @PreAuthorize("hasRole('ROLE_READ')") - @Transactional(readOnly = true, rollbackFor = {Throwable.class}) + @Transactional(readOnly = true, rollbackFor = { Throwable.class }) public List<RoleTO> search(final NodeCond searchCondition) throws InvalidSearchConditionException { @@ -182,7 +182,7 @@ public class RoleController extends Abst } @PreAuthorize("hasRole('ROLE_READ')") - @Transactional(readOnly = true, rollbackFor = {Throwable.class}) + @Transactional(readOnly = true, rollbackFor = { Throwable.class }) public List<RoleTO> search(final NodeCond searchCondition, final int page, final int size) throws InvalidSearchConditionException { @@ -204,7 +204,7 @@ public class RoleController extends Abst } @PreAuthorize("hasRole('ROLE_READ')") - @Transactional(readOnly = true, rollbackFor = {Throwable.class}) + @Transactional(readOnly = true, rollbackFor = { Throwable.class }) public int searchCount(final NodeCond searchCondition) throws InvalidSearchConditionException { @@ -310,7 +310,7 @@ public class RoleController extends Abst final List<SyncopeRole> toBeDeprovisioned = new ArrayList<SyncopeRole>(); final SyncopeRole syncopeRole = roleDAO.find(roleId); - + if (syncopeRole != null) { toBeDeprovisioned.add(syncopeRole); Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java Wed Dec 4 15:34:14 2013 @@ -211,7 +211,7 @@ public class LDAPMembershipSyncActions e updated = uwfAdapter.update(userMod); List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds( - updated, Collections.singleton(resourceName)); + updated, false, Collections.singleton(resourceName)); taskExecutor.execute(tasks); result = Result.SUCCESS; Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java Wed Dec 4 15:34:14 2013 @@ -475,7 +475,7 @@ public class SyncopeSyncResultHandler im final List<ConnectorObject> found = connector.search(objectClass, new EqualsFilter(new Name(name)), connector.getOperationOptions( - attrUtil.getMappingItems(syncTask.getResource(), MappingPurpose.SYNCHRONIZATION))); + attrUtil.getMappingItems(syncTask.getResource(), MappingPurpose.SYNCHRONIZATION))); if (found.isEmpty()) { LOG.debug("No {} found on {} with __NAME__ {}", objectClass, syncTask.getResource(), name); @@ -678,7 +678,8 @@ public class SyncopeSyncResultHandler im } List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds( - updated, Collections.singleton(syncTask.getResource().getName())); + updated, updated.getResult().getKey().getPassword() != null, + Collections.singleton(syncTask.getResource().getName())); taskExecutor.execute(tasks); Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java Wed Dec 4 15:34:14 2013 @@ -247,8 +247,12 @@ public final class MappingUtil { } } - result = new AbstractMap.SimpleEntry<String, Attribute>(null, - AttributeBuilder.buildPassword(passwordAttrValue.toCharArray())); + if (passwordAttrValue == null) { + result = null; + } else { + result = new AbstractMap.SimpleEntry<String, Attribute>(null, + AttributeBuilder.buildPassword(passwordAttrValue.toCharArray())); + } } else { if ((schema != null && schema.isMultivalue()) || AttributableUtil.getInstance(subject).getType() != mapItem.getIntMappingType().getAttributableType()) { Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java Wed Dec 4 15:34:14 2013 @@ -22,9 +22,12 @@ import static org.junit.Assert.assertNot import java.io.InputStream; import java.net.URI; +import java.util.Hashtable; +import java.util.Map; import java.util.Properties; import java.util.UUID; - +import javax.naming.Context; +import javax.naming.directory.InitialDirContext; import javax.sql.DataSource; import javax.ws.rs.core.Response; import org.apache.commons.io.IOUtils; @@ -58,6 +61,7 @@ import org.apache.syncope.common.to.Reso import org.apache.syncope.common.to.RoleTO; import org.apache.syncope.common.to.UserTO; import org.apache.syncope.common.types.AttributableType; +import org.apache.syncope.common.types.ConnConfProperty; import org.apache.syncope.common.types.RESTHeaders; import org.apache.syncope.common.types.SchemaType; import org.apache.syncope.core.util.PasswordEncoder; @@ -70,7 +74,7 @@ import org.springframework.test.context. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = {"classpath:testJDBCContext.xml"}) +@ContextConfiguration(locations = { "classpath:testJDBCContext.xml" }) public abstract class AbstractTest { /** @@ -257,14 +261,14 @@ public abstract class AbstractTest { protected UserTO deleteUser(final Long id) { return userService.delete(id).readEntity(UserTO.class); } - + public <T> T getObject(final URI location, final Class<?> serviceClass, final Class<T> resultClass) { WebClient webClient = WebClient.fromClient(WebClient.client(adminClient.getService(serviceClass))); webClient.accept(clientFactory.getContentType().getMediaType()).to(location.toASCIIString(), false); return webClient.get(resultClass); } - + @SuppressWarnings("unchecked") protected <T extends AbstractSchemaTO> T createSchema(final AttributableType kind, final SchemaType type, final T schemaTO) { @@ -321,4 +325,32 @@ public abstract class AbstractTest { } return getObject(response.getLocation(), ResourceService.class, ResourceTO.class); } + + protected Object getLdapRemoteObject(final String objectDn) { + return getLdapRemoteObject(null, null, objectDn); + } + + @SuppressWarnings({ "unchecked", "rawtypes", "UseOfObsoleteCollectionType" }) + protected Object getLdapRemoteObject(final String bindDn, final String bindPwd, final String objectDn) { + ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP); + final Map<String, ConnConfProperty> ldapConnConf = + connectorService.read(ldapRes.getConnectorId()).getConfigurationMap(); + + Hashtable env = new Hashtable(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + env.put(Context.PROVIDER_URL, "ldap://" + ldapConnConf.get("host").getValues().get(0) + + ":" + ldapConnConf.get("port").getValues().get(0) + "/"); + env.put(Context.SECURITY_AUTHENTICATION, "simple"); + env.put(Context.SECURITY_PRINCIPAL, + bindDn == null ? ldapConnConf.get("principal").getValues().get(0) : bindDn); + env.put(Context.SECURITY_CREDENTIALS, + bindPwd == null ? ldapConnConf.get("credentials").getValues().get(0) : bindPwd); + + try { + final InitialDirContext ctx = new InitialDirContext(env); + return ctx.lookup(objectDn); + } catch (Exception e) { + return null; + } + } } Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java Wed Dec 4 15:34:14 2013 @@ -28,11 +28,7 @@ import static org.junit.Assert.fail; import java.io.IOException; import java.io.InputStream; import java.security.AccessControlException; -import java.util.Hashtable; import java.util.List; -import java.util.Map; -import javax.naming.Context; -import javax.naming.directory.InitialDirContext; import javax.ws.rs.core.Response; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; @@ -41,13 +37,11 @@ import org.apache.syncope.common.mod.Rol import org.apache.syncope.common.services.RoleService; import org.apache.syncope.common.to.ConnObjectTO; import org.apache.syncope.common.to.ResourceNameTO; -import org.apache.syncope.common.to.ResourceTO; import org.apache.syncope.common.to.RoleTO; import org.apache.syncope.common.to.SchemaTO; import org.apache.syncope.common.to.UserTO; import org.apache.syncope.common.types.AttributableType; import org.apache.syncope.common.types.ClientExceptionType; -import org.apache.syncope.common.types.ConnConfProperty; import org.apache.syncope.common.types.Preference; import org.apache.syncope.common.types.RESTHeaders; import org.apache.syncope.common.types.ResourceAssociationActionType; @@ -592,38 +586,17 @@ public class RoleTestITCase extends Abst roleService.read(parent.getId()); fail(); } catch (SyncopeClientException scce) { - // ignore + assertNotNull(scce); } try { roleService.read(child.getId()); fail(); } catch (SyncopeClientException scce) { - // ignore + assertNotNull(scce); } assertNull(getLdapRemoteObject(parentRemoteObject.getAttrMap().get(Name.NAME).getValues().get(0))); assertNull(getLdapRemoteObject(childRemoteObject.getAttrMap().get(Name.NAME).getValues().get(0))); } - - private Object getLdapRemoteObject(final String name) { - ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP); - final Map<String, ConnConfProperty> ldapConnConf = - connectorService.read(ldapRes.getConnectorId()).getConfigurationMap(); - - Hashtable env = new Hashtable(); - env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); - env.put(Context.PROVIDER_URL, "ldap://" + ldapConnConf.get("host").getValues().get(0) - + ":" + ldapConnConf.get("port").getValues().get(0) + "/"); - env.put(Context.SECURITY_AUTHENTICATION, "simple"); - env.put(Context.SECURITY_PRINCIPAL, ldapConnConf.get("principal").getValues().get(0)); - env.put(Context.SECURITY_CREDENTIALS, ldapConnConf.get("credentials").getValues().get(0)); - - try { - final InitialDirContext ctx = new InitialDirContext(env); - return ctx.lookup(name); - } catch (Exception e) { - return null; - } - } } Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java Wed Dec 4 15:34:14 2013 @@ -73,6 +73,7 @@ import org.identityconnectors.framework. import java.io.IOException; import java.io.InputStream; +import javax.naming.NamingException; import javax.ws.rs.core.EntityTag; import javax.xml.ws.WebServiceException; import org.apache.commons.lang3.StringUtils; @@ -81,6 +82,7 @@ import org.apache.syncope.client.Syncope import org.apache.syncope.common.services.UserService; import org.apache.syncope.common.types.Preference; import org.apache.syncope.common.types.RESTHeaders; +import org.identityconnectors.framework.common.objects.Name; import org.junit.Assume; import org.junit.FixMethodOrder; import org.junit.Test; @@ -1060,7 +1062,6 @@ public class UserTestITCase extends Abst // 2. try to update by adding a resource, but no password: must fail UserMod userMod = AttributableOperations.diff(toBeUpdated, original); - assertNotNull(userMod); toBeUpdated = updateUser(userMod); @@ -1447,7 +1448,7 @@ public class UserTestITCase extends Abst assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus()); ConnObjectTO connObjectTO = - resourceService.getConnectorObject("resource-db-virattr", AttributableType.USER, userTO.getId()); + resourceService.getConnectorObject(RESOURCE_NAME_DBVIRATTR, AttributableType.USER, userTO.getId()); assertNotNull(connObjectTO); assertEquals("virtualvalue", connObjectTO.getAttrMap().get("USERNAME").getValues().get(0)); // ---------------------------------- @@ -1636,7 +1637,7 @@ public class UserTestITCase extends Abst UserTO actual = createUser(userTO); assertNotNull(actual); - final ConnObjectTO connObjectTO = + ConnObjectTO connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_CSV, AttributableType.USER, actual.getId()); assertNull(connObjectTO.getAttrMap().get("email")); } @@ -2043,4 +2044,38 @@ public class UserTestITCase extends Abst userTO = userService.read(userTO.getId()); assertTrue(userTO.getUsername().endsWith("XX")); } + + @Test + public void issueSYNCOPE454() throws NamingException { + // 1. create user with LDAP resource (with 'Generate password if missing' enabled) + UserTO userTO = getUniqueSampleTO("syncope...@syncope.apache.org"); + userTO.getResources().add(RESOURCE_NAME_LDAP); + userTO = createUser(userTO); + assertNotNull(userTO); + + // 2. read resource configuration for LDAP binding + ConnObjectTO connObject = + resourceService.getConnectorObject(RESOURCE_NAME_LDAP, AttributableType.USER, userTO.getId()); + + // 3. try (and succeed) to perform simple LDAP binding with provided password ('password123') + assertNotNull(getLdapRemoteObject( + connObject.getAttrMap().get(Name.NAME).getValues().get(0), + "password123", + connObject.getAttrMap().get(Name.NAME).getValues().get(0))); + + // 4. update user without any password change request + UserMod userMod = new UserMod(); + userMod.setId(userTO.getId()); + userMod.setPwdPropRequest(new StatusMod()); + userMod.getAttrsToUpdate().add(attributeMod("surname", "surname2")); + + userService.update(userTO.getId(), userMod); + + // 5. try (and succeed again) to perform simple LDAP binding: password has not changed + assertNotNull(getLdapRemoteObject( + connObject.getAttrMap().get(Name.NAME).getValues().get(0), + "password123", + connObject.getAttrMap().get(Name.NAME).getValues().get(0))); + } + } Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java?rev=1547823&r1=1547822&r2=1547823&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java Wed Dec 4 15:34:14 2013 @@ -136,8 +136,7 @@ public class VirAttrTestITCase extends A userTO = userService.status(userTO.getId(), statusMod).readEntity(UserTO.class); assertEquals("suspended", userTO.getStatus()); - connObjectTO = - resourceService.getConnectorObject(RESOURCE_NAME_WS2, AttributableType.USER, userTO.getId()); + connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, AttributableType.USER, userTO.getId()); assertNotNull(connObjectTO); assertFalse(connObjectTO.getAttrMap().get("NAME").getValues().isEmpty()); assertEquals("virtualvalue2", connObjectTO.getAttrMap().get("NAME").getValues().get(0)); @@ -147,8 +146,7 @@ public class VirAttrTestITCase extends A userTO = userService.status(userTO.getId(), statusMod).readEntity(UserTO.class); assertEquals("active", userTO.getStatus()); - connObjectTO = - resourceService.getConnectorObject(RESOURCE_NAME_WS2, AttributableType.USER, userTO.getId()); + connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, AttributableType.USER, userTO.getId()); assertNotNull(connObjectTO); assertFalse(connObjectTO.getAttrMap().get("NAME").getValues().isEmpty()); assertEquals("virtualvalue2", connObjectTO.getAttrMap().get("NAME").getValues().get(0));