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));


Reply via email to