This is an automated email from the ASF dual-hosted git repository.

skylark17 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new ed0555a  [SYNCOPE-957] Added missing sections for reconciliation 
process
ed0555a is described below

commit ed0555ad79574f23a447bb775bd430120d55437e
Author: skylark17 <[email protected]>
AuthorDate: Wed Dec 11 10:00:43 2019 +0100

    [SYNCOPE-957] Added missing sections for reconciliation process
---
 ...DirectoryPanelAditionalActionLinksProvider.java |  17 +-
 .../console/panels/LinkedAccountModalPanel.java    | 178 +++++++++++++++------
 .../panels/LinkedAccountsStatusModalPanel.java     |  39 +++++
 .../console/status/AnyStatusDirectoryPanel.java    |  29 ++++
 .../client/console/status/ReconTaskPanel.java      |   4 +-
 .../wizards/any/LinkedAccountDetailsPanel.java     |  26 ++-
 .../wizards/any/LinkedAccountWizardBuilder.java    |  19 +--
 ...DirectoryPanelAditionalActionLinksProvider.java |   3 +-
 ...DirectoryPanelAditionalActionLinksProvider.java |   3 +-
 .../client/console/panels/UserDirectoryPanel.java  |   2 +-
 .../console/panels/LinkedAccountModalPanel.html    |   4 +-
 ...el.html => LinkedAccountsStatusModalPanel.html} |   5 +-
 .../syncope/core/logic/ReconciliationLogic.java    |   2 +-
 13 files changed, 241 insertions(+), 90 deletions(-)

diff --git 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
index 11df282..2982849 100644
--- 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
+++ 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAditionalActionLinksProvider.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.commons;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.syncope.client.console.panels.LinkedAccountModalPanel;
+import org.apache.syncope.client.console.rest.UserRestClient;
 import org.apache.syncope.client.console.status.AnyStatusModal;
 import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.Action;
@@ -44,7 +45,7 @@ public class IdMAnyDirectoryPanelAditionalActionLinksProvider
 
     @Override
     public List<Action<UserTO>> get(
-            final UserTO modelObject,
+            final IModel<UserTO> model,
             final String realm,
             final BaseModal<AnyWrapper<UserTO>> modal,
             final String header,
@@ -59,7 +60,7 @@ public class IdMAnyDirectoryPanelAditionalActionLinksProvider
             @Override
             public void onClick(final AjaxRequestTarget target, final UserTO 
ignore) {
                 IModel<AnyWrapper<UserTO>> formModel = new 
CompoundPropertyModel<>(
-                        new AnyWrapper<>(modelObject));
+                        new AnyWrapper<>(model.getObject()));
                 modal.setFormModel(formModel);
 
                 target.add(modal.setContent(new AnyStatusModal<>(
@@ -76,7 +77,7 @@ public class IdMAnyDirectoryPanelAditionalActionLinksProvider
         }, ActionLink.ActionType.ENABLE);
         enable.setEntitlements(IdRepoEntitlement.USER_UPDATE);
         enable.setOnConfirm(false);
-        enable.setRealms(realm, modelObject.getDynRealms());
+        enable.setRealms(realm, model.getObject().getDynRealms());
         actions.add(enable);
 
         Action<UserTO> manageResources = new Action<>(new ActionLink<UserTO>() 
{
@@ -85,8 +86,9 @@ public class IdMAnyDirectoryPanelAditionalActionLinksProvider
 
             @Override
             public void onClick(final AjaxRequestTarget target, final UserTO 
ignore) {
+                model.setObject(new 
UserRestClient().read(model.getObject().getKey()));
                 IModel<AnyWrapper<UserTO>> formModel = new 
CompoundPropertyModel<>(
-                        new AnyWrapper<>(modelObject));
+                        new AnyWrapper<>(model.getObject()));
                 modal.setFormModel(formModel);
 
                 target.add(modal.setContent(new AnyStatusModal<>(
@@ -104,7 +106,7 @@ public class 
IdMAnyDirectoryPanelAditionalActionLinksProvider
         manageResources.setEntitlements(
                 String.format("%s,%s", IdRepoEntitlement.USER_READ, 
IdRepoEntitlement.USER_UPDATE));
         manageResources.setOnConfirm(false);
-        manageResources.setRealms(realm, modelObject.getDynRealms());
+        manageResources.setRealms(realm, model.getObject().getDynRealms());
         actions.add(manageResources);
 
         Action<UserTO> manageAccounts = new Action<>(new ActionLink<UserTO>() {
@@ -113,8 +115,9 @@ public class 
IdMAnyDirectoryPanelAditionalActionLinksProvider
 
             @Override
             public void onClick(final AjaxRequestTarget target, final UserTO 
ignore) {
+                model.setObject(new 
UserRestClient().read(model.getObject().getKey()));
                 modal.setFooterVisible(false);
-                target.add(modal.setContent(new LinkedAccountModalPanel(modal, 
modelObject, pageRef)));
+                target.add(modal.setContent(new LinkedAccountModalPanel(modal, 
model, pageRef, false)));
 
                 modal.header(new Model<>(header));
 
@@ -124,7 +127,7 @@ public class 
IdMAnyDirectoryPanelAditionalActionLinksProvider
         manageAccounts.setEntitlements(
                 String.format("%s,%s", IdRepoEntitlement.USER_READ, 
IdRepoEntitlement.USER_UPDATE));
         manageAccounts.setOnConfirm(false);
-        manageAccounts.setRealms(realm, modelObject.getDynRealms());
+        manageAccounts.setRealms(realm, model.getObject().getDynRealms());
         actions.add(manageAccounts);
 
         return actions;
diff --git 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
index a5d64db..899bda5 100644
--- 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
+++ 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
@@ -18,7 +18,8 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import java.io.Serializable;
+import static org.apache.syncope.client.console.panels.DirectoryPanel.LOG;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -27,17 +28,22 @@ import 
org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.rest.UserRestClient;
+import org.apache.syncope.client.console.status.ReconStatusPanel;
+import org.apache.syncope.client.console.status.ReconTaskPanel;
 import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import 
org.apache.syncope.client.console.wizards.any.LinkedAccountWizardBuilder;
 import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.panels.ModalPanel;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.request.LinkedAccountUR;
 import org.apache.syncope.common.lib.request.UserUR;
 import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.common.lib.types.PatchOperation;
@@ -45,10 +51,12 @@ import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.model.StringResourceModel;
 
-public class LinkedAccountModalPanel extends AbstractModalPanel<Serializable> {
+public class LinkedAccountModalPanel extends Panel implements ModalPanel {
 
     private static final long serialVersionUID = -4603032036433309900L;
 
@@ -66,20 +74,22 @@ public class LinkedAccountModalPanel extends 
AbstractModalPanel<Serializable> {
 
     @SuppressWarnings("unchecked")
     public LinkedAccountModalPanel(
-            final BaseModal<?> modal,
-            final UserTO userTO,
-            final PageReference pageRef) {
+            final BaseModal<?> baseModal,
+            final IModel<UserTO> model,
+            final PageReference pageRef,
+            final boolean recounciliationOnly) {
 
-        super((BaseModal<Serializable>) modal, pageRef);
+        super(BaseModal.getContentId(), model);
 
-        UserTO readUserTO = userRestClient.read(userTO.getKey());
+        final MultilevelPanel mlp = new MultilevelPanel("mlpContainer");
+        mlp.setOutputMarkupId(true);
 
         setOutputMarkupId(true);
 
         actionTogglePanel = new ActionLinksTogglePanel<>("toggle", pageRef);
         add(actionTogglePanel);
 
-        wizard = new LinkedAccountWizardBuilder(readUserTO.getKey(), pageRef);
+        wizard = new LinkedAccountWizardBuilder(model, pageRef);
 
         final ListViewPanel.Builder<LinkedAccountTO> builder = new 
ListViewPanel.Builder<LinkedAccountTO>(
                 LinkedAccountTO.class, pageRef) {
@@ -116,7 +126,7 @@ public class LinkedAccountModalPanel extends 
AbstractModalPanel<Serializable> {
                 checkAddButton();
 
                 linkedAccountTOs.clear();
-                
linkedAccountTOs.addAll(userRestClient.read(userTO.getKey()).getLinkedAccounts());
+                linkedAccountTOs.addAll(model.getObject().getLinkedAccounts());
                 sortLinkedAccounts();
 
                 ListViewPanel.class.cast(list).refreshList(linkedAccountTOs);
@@ -131,7 +141,7 @@ public class LinkedAccountModalPanel extends 
AbstractModalPanel<Serializable> {
             }
         };
 
-        linkedAccountTOs = new ArrayList<>(readUserTO.getLinkedAccounts());
+        linkedAccountTOs = new 
ArrayList<>(model.getObject().getLinkedAccounts());
         sortLinkedAccounts();
 
         builder.setItems(linkedAccountTOs);
@@ -145,56 +155,131 @@ public class LinkedAccountModalPanel extends 
AbstractModalPanel<Serializable> {
 
             @Override
             public void onClick(final AjaxRequestTarget target, final 
LinkedAccountTO linkedAccountTO) {
-                try {
-                    send(LinkedAccountModalPanel.this, Broadcast.DEPTH,
-                            new 
AjaxWizard.NewItemActionEvent<>(linkedAccountTO, 1, target).setResourceModel(
-                                    new 
StringResourceModel("inner.edit.linkedAccount",
-                                            LinkedAccountModalPanel.this,
-                                            Model.of(linkedAccountTO))));
-                } catch (SyncopeClientException e) {
-                    LOG.error("While contacting linked account", e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? 
e.getClass().getName() : e.getMessage());
-                    ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
+                mlp.next(linkedAccountTO.getResource(),
+                        new ReconStatusPanel(
+                                linkedAccountTO.getResource(),
+                                model.getObject().getType(),
+                                model.getObject().getKey()),
+                        target);
+                target.add(mlp);
+
+                ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
+                send(LinkedAccountModalPanel.this, Broadcast.BREADTH,
+                        new 
ActionLinksTogglePanel.ActionLinkToggleCloseEventPayload(target));
+            }
+        }, ActionLink.ActionType.VIEW, IdRepoEntitlement.USER_READ);
+
+        if (!recounciliationOnly) {
+            builder.addAction(new ActionLink<LinkedAccountTO>() {
+
+                private static final long serialVersionUID = 
2555747430358755813L;
+
+                @Override
+                public void onClick(final AjaxRequestTarget target, final 
LinkedAccountTO linkedAccountTO) {
+                    try {
+                        send(LinkedAccountModalPanel.this, Broadcast.DEPTH,
+                                new 
AjaxWizard.NewItemActionEvent<>(linkedAccountTO, 1, target).
+                                        setResourceModel(new 
StringResourceModel("inner.edit.linkedAccount",
+                                                LinkedAccountModalPanel.this,
+                                                Model.of(linkedAccountTO))));
+
+                    } catch (SyncopeClientException e) {
+                        LOG.error("While contacting linked account", e);
+                        SyncopeConsoleSession.get().error(
+                                StringUtils.isBlank(e.getMessage()) ? 
e.getClass().getName() : e.getMessage());
+                        ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
+                    }
+
+                    send(LinkedAccountModalPanel.this, Broadcast.BREADTH,
+                            new 
ActionLinksTogglePanel.ActionLinkToggleCloseEventPayload(target));
                 }
+            }, ActionLink.ActionType.EDIT, IdRepoEntitlement.USER_READ);
+        }
+
+        builder.addAction(new ActionLink<LinkedAccountTO>() {
 
+            private static final long serialVersionUID = 2555747430358755813L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target, final 
LinkedAccountTO linkedAccountTO) {
+                mlp.next("PUSH " + linkedAccountTO.getResource(),
+                        new ReconTaskPanel(
+                                linkedAccountTO.getResource(),
+                                new PushTaskTO(),
+                                model.getObject().getType(),
+                                null,
+                                linkedAccountTO.getConnObjectKeyValue(),
+                                true,
+                                mlp,
+                                pageRef),
+                        target);
+                target.add(mlp);
+
+                ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
                 send(LinkedAccountModalPanel.this, Broadcast.BREADTH,
                         new 
ActionLinksTogglePanel.ActionLinkToggleCloseEventPayload(target));
             }
-        }, ActionLink.ActionType.EDIT, IdRepoEntitlement.USER_READ).
+        }, ActionLink.ActionType.RECONCILIATION_PUSH, 
IdRepoEntitlement.USER_READ).
                 addAction(new ActionLink<LinkedAccountTO>() {
 
                     private static final long serialVersionUID = 
2555747430358755813L;
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final 
LinkedAccountTO linkedAccountTO) {
-                        try {
-                            LinkedAccountUR linkedAccountPatch = new 
LinkedAccountUR.Builder().
-                                    operation(PatchOperation.DELETE).
-                                    linkedAccountTO(linkedAccountTO).build();
-                            
linkedAccountPatch.setLinkedAccountTO(linkedAccountTO);
-                            UserUR patch = new UserUR();
-                            patch.setKey(readUserTO.getKey());
-                            patch.getLinkedAccounts().add(linkedAccountPatch);
-                            
userRestClient.update(userRestClient.read(userTO.getKey()).getETagValue(), 
patch);
-                            linkedAccountTOs.remove(linkedAccountTO);
-
-                            
SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                        } catch (Exception e) {
-                            LOG.error("While removing linked account {}", 
linkedAccountTO.getKey(), e);
-                            
SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
-                        }
-
-                        checkAddButton();
+                        mlp.next("PULL " + linkedAccountTO.getResource(),
+                                new ReconTaskPanel(
+                                        linkedAccountTO.getResource(),
+                                        new PullTaskTO(),
+                                        model.getObject().getType(),
+                                        null,
+                                        
linkedAccountTO.getConnObjectKeyValue(),
+                                        true,
+                                        mlp,
+                                        pageRef),
+                                target);
+                        target.add(mlp);
+
                         ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
-                        send(LinkedAccountModalPanel.this, Broadcast.DEPTH, 
new ListViewPanel.ListViewReload<>(target));
+                        send(LinkedAccountModalPanel.this, Broadcast.BREADTH,
+                                new 
ActionLinksTogglePanel.ActionLinkToggleCloseEventPayload(target));
+                    }
+                }, ActionLink.ActionType.RECONCILIATION_PULL, 
IdRepoEntitlement.USER_READ);
+
+        if (!recounciliationOnly) {
+            builder.addAction(new ActionLink<LinkedAccountTO>() {
+
+                private static final long serialVersionUID = 
2555747430358755813L;
+
+                @Override
+                public void onClick(final AjaxRequestTarget target, final 
LinkedAccountTO linkedAccountTO) {
+                    try {
+                        LinkedAccountUR linkedAccountPatch = new 
LinkedAccountUR.Builder().
+                                operation(PatchOperation.DELETE).
+                                linkedAccountTO(linkedAccountTO).build();
+                        linkedAccountPatch.setLinkedAccountTO(linkedAccountTO);
+                        UserUR patch = new UserUR();
+                        patch.setKey(model.getObject().getKey());
+                        patch.getLinkedAccounts().add(linkedAccountPatch);
+                        
model.setObject(userRestClient.update(model.getObject().getETagValue(), 
patch).getEntity());
+                        linkedAccountTOs.remove(linkedAccountTO);
+
+                        
SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                    } catch (Exception e) {
+                        LOG.error("While removing linked account {}", 
linkedAccountTO.getKey(), e);
+                        
SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                                ? e.getClass().getName() : e.getMessage());
                     }
-                }, ActionLink.ActionType.DELETE, 
IdRepoEntitlement.USER_UPDATE, true);
+
+                    checkAddButton();
+                    ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
+                    send(LinkedAccountModalPanel.this, Broadcast.DEPTH, new 
ListViewPanel.ListViewReload<>(target));
+                }
+            }, ActionLink.ActionType.DELETE, IdRepoEntitlement.USER_UPDATE, 
true);
+        }
 
         builder.addNewItemPanelBuilder(wizard);
 
-        list = builder.build("linkedAccountsList");
+        list = builder.build(MultilevelPanel.FIRST_LEVEL_ID);
         list.setOutputMarkupId(true);
         
list.setReadOnly(!SyncopeConsoleSession.get().owns(IdRepoEntitlement.USER_UPDATE));
 
@@ -213,8 +298,9 @@ public class LinkedAccountModalPanel extends 
AbstractModalPanel<Serializable> {
                                 LinkedAccountModalPanel.this)));
             }
         };
-        list.addOrReplaceInnerObject(addAjaxLink);
-        add(list);
+        
list.addOrReplaceInnerObject(addAjaxLink.setEnabled(!recounciliationOnly).setVisible(!recounciliationOnly));
+
+        add(mlp.setFirstLevel(list));
     }
 
     private void sortLinkedAccounts() {
diff --git 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountsStatusModalPanel.java
 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountsStatusModalPanel.java
new file mode 100644
index 0000000..ea4fc85
--- /dev/null
+++ 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountsStatusModalPanel.java
@@ -0,0 +1,39 @@
+/*
+ * 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.client.console.panels;
+
+import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.model.IModel;
+
+public class LinkedAccountsStatusModalPanel extends 
MultilevelPanel.SecondLevel {
+
+    private static final long serialVersionUID = 8804361394735366181L;
+
+    public LinkedAccountsStatusModalPanel(
+            final BaseModal<?> baseModal,
+            final IModel<UserTO> model,
+            final PageReference pageRef) {
+
+        super(MultilevelPanel.SECOND_LEVEL_ID);
+
+        add(new LinkedAccountModalPanel(baseModal, model, pageRef, 
true).setOutputMarkupId(true));
+    }
+}
diff --git 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
index 31c0af0..651b2c4 100644
--- 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
+++ 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
@@ -32,6 +32,7 @@ import org.apache.syncope.client.ui.commons.status.StatusBean;
 import org.apache.syncope.client.ui.commons.status.StatusUtils;
 import org.apache.syncope.client.console.panels.DirectoryPanel;
 import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
+import org.apache.syncope.client.console.panels.LinkedAccountsStatusModalPanel;
 import org.apache.syncope.client.console.panels.MultilevelPanel;
 import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
 import org.apache.syncope.client.console.rest.AnyObjectRestClient;
@@ -63,6 +64,7 @@ import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
 import org.apache.wicket.model.StringResourceModel;
 
 public class AnyStatusDirectoryPanel
@@ -244,6 +246,33 @@ public class AnyStatusDirectoryPanel
             }, ActionLink.ActionType.RECONCILIATION_PULL, 
IdRepoEntitlement.TASK_EXECUTE);
         }
 
+        if (anyTO instanceof UserTO && 
!UserTO.class.cast(anyTO).getLinkedAccounts().isEmpty()) {
+            UserTO userTO = UserTO.class.cast(anyTO);
+
+            if (!userTO.getLinkedAccounts().isEmpty()
+                    && 
userTO.getLinkedAccounts().stream().anyMatch(linkedAccountTO -> {
+                        return 
linkedAccountTO.getResource().equals(model.getObject().getResource());
+                    })) {
+
+                panel.add(new ActionLink<StatusBean>() {
+
+                    private static final long serialVersionUID = 
5168094747477174155L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final 
StatusBean bean) {
+                        multiLevelPanelRef.next("ACCOUNTS",
+                                new LinkedAccountsStatusModalPanel(
+                                        baseModal, 
Model.of(UserTO.class.cast(anyTO)), pageRef),
+                                target);
+                        target.add(multiLevelPanelRef);
+                        
AnyStatusDirectoryPanel.this.getTogglePanel().close(target);
+                    }
+                }, ActionLink.ActionType.MANAGE_ACCOUNTS,
+                        String.format("%s,%s,%s", IdRepoEntitlement.USER_READ, 
IdRepoEntitlement.USER_UPDATE,
+                                IdMEntitlement.RESOURCE_GET_CONNOBJECT));
+            }
+        }
+
         return panel;
     }
 
diff --git 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
index c1ff9a9..520555e 100644
--- 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
+++ 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
@@ -187,7 +187,9 @@ public class ReconTaskPanel extends 
MultilevelPanel.SecondLevel {
                 } catch (Exception e) {
                     LOG.error("While attempting reconciliation on {}", 
reconQuery, form.getModelObject(), e);
                     SyncopeConsoleSession.get().error(resource + ": "
-                            + (StringUtils.isBlank(e.getMessage()) ? 
e.getClass().getName() : e.getMessage()));
+                            + (StringUtils.isBlank(e.getMessage())
+                            ? e.getClass().getName()
+                            : 
StringUtils.abbreviate(StringUtils.normalizeSpace(e.getMessage()), 280)));
                 }
                 multiLevelPanelRef.prev(target);
                 ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
diff --git 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
index cccf7b8..4e75d18 100644
--- 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
+++ 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
@@ -18,11 +18,8 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
@@ -49,6 +46,7 @@ import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.util.time.Duration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import java.util.concurrent.atomic.AtomicReference;
 
 public class LinkedAccountDetailsPanel extends WizardStep {
 
@@ -60,7 +58,7 @@ public class LinkedAccountDetailsPanel extends WizardStep {
 
     private final ResourceRestClient resourceRestClient = new 
ResourceRestClient();
 
-    private ArrayList<String> connObjectKeyFieldValues;
+    private List<String> connObjectKeyFieldValues;
 
     public LinkedAccountDetailsPanel(final LinkedAccountTO linkedAccountTO) {
         super();
@@ -157,11 +155,10 @@ public class LinkedAccountDetailsPanel extends WizardStep 
{
             final String resource,
             final String searchTerm) {
 
-        Set<String> choices = new HashSet<>();
-        String resourceRemoteKey = ConnIdSpecialName.NAME;
+        AtomicReference<String> resourceRemoteKey = new 
AtomicReference<>(ConnIdSpecialName.NAME);
         try {
-            resourceRemoteKey = 
resourceRestClient.read(resource).getProvision(AnyTypeKind.USER.name()).get().
-                    getMapping().getConnObjectKeyItem().getExtAttrName();
+            
resourceRemoteKey.set(resourceRestClient.read(resource).getProvision(AnyTypeKind.USER.name()).get().
+                    getMapping().getConnObjectKeyItem().getExtAttrName());
         } catch (Exception ex) {
             LOG.error("While reading mapping for resource {}", resource, ex);
         }
@@ -169,19 +166,16 @@ public class LinkedAccountDetailsPanel extends WizardStep 
{
         ConnObjectTOQuery.Builder builder = new 
ConnObjectTOQuery.Builder().size(SEARCH_SIZE);
         if (StringUtils.isNotBlank(searchTerm)) {
             
builder.fiql(SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
-                    is(resourceRemoteKey).equalTo(searchTerm + 
"*").query()).build();
+                    is(resourceRemoteKey.get()).equalTo(searchTerm + 
"*").query()).build();
         }
         Pair<String, List<ConnObjectTO>> items = 
resourceRestClient.searchConnObjects(resource,
                 AnyTypeKind.USER.name(),
                 builder,
-                new SortParam<>(resourceRemoteKey, true));
+                new SortParam<>(resourceRemoteKey.get(), true));
 
-        choices.addAll(items.getRight().stream().map(item -> {
-            return 
item.getAttr(ConnIdSpecialName.UID).get().getValues().get(0);
-        }).collect(Collectors.toSet()));
-
-        connObjectKeyFieldValues = new ArrayList<>(choices);
-        Collections.sort(connObjectKeyFieldValues);
+        connObjectKeyFieldValues = items.getRight().stream().
+                map(item -> 
item.getAttr(resourceRemoteKey.get()).get().getValues().get(0)).
+                collect(Collectors.toList());
         ajaxTextFieldPanel.setChoices(connObjectKeyFieldValues);
     }
 
diff --git 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
index 371ab09..ae5076d 100644
--- 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
+++ 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
@@ -35,6 +35,7 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.wizard.WizardModel;
+import org.apache.wicket.model.IModel;
 
 /**
  * Accounts wizard builder.
@@ -45,19 +46,15 @@ public class LinkedAccountWizardBuilder extends 
BaseAjaxWizardBuilder<LinkedAcco
 
     private final UserRestClient userRestClient = new UserRestClient();
 
-    private UserTO userTO;
+    private final IModel<UserTO> model;
 
-    private final String userKey;
-
-    public LinkedAccountWizardBuilder(final String userKey, final 
PageReference pageRef) {
+    public LinkedAccountWizardBuilder(final IModel<UserTO> model, final 
PageReference pageRef) {
         super(new LinkedAccountTO(), pageRef);
-        this.userKey = userKey;
-        this.userTO = userRestClient.read(userKey);
+        this.model = model;
     }
 
     @Override
     public AjaxWizard<LinkedAccountTO> build(final String id, final 
AjaxWizard.Mode mode) {
-        this.userTO = userRestClient.read(userKey);
         return super.build(id, mode);
     }
 
@@ -65,7 +62,7 @@ public class LinkedAccountWizardBuilder extends 
BaseAjaxWizardBuilder<LinkedAcco
     protected WizardModel buildModelSteps(final LinkedAccountTO modelObject, 
final WizardModel wizardModel) {
         wizardModel.add(new LinkedAccountDetailsPanel(modelObject));
         wizardModel.add(new LinkedAccountCredentialsPanel(modelObject));
-        wizardModel.add(new LinkedAccountPlainAttrsPanel(new 
EntityWrapper<>(modelObject), userTO));
+        wizardModel.add(new LinkedAccountPlainAttrsPanel(new 
EntityWrapper<>(modelObject), model.getObject()));
         wizardModel.add(new LinkedAccountPrivilegesPanel(modelObject));
         return wizardModel;
     }
@@ -77,9 +74,9 @@ public class LinkedAccountWizardBuilder extends 
BaseAjaxWizardBuilder<LinkedAcco
         LinkedAccountUR linkedAccountPatch = new 
LinkedAccountUR.Builder().linkedAccountTO(modelObject).build();
         linkedAccountPatch.setLinkedAccountTO(modelObject);
         UserUR patch = new UserUR();
-        patch.setKey(userTO.getKey());
+        patch.setKey(model.getObject().getKey());
         patch.getLinkedAccounts().add(linkedAccountPatch);
-        userRestClient.update(userTO.getETagValue(), patch);
+        
model.setObject(userRestClient.update(model.getObject().getETagValue(), 
patch).getEntity());
 
         return modelObject;
     }
@@ -97,7 +94,7 @@ public class LinkedAccountWizardBuilder extends 
BaseAjaxWizardBuilder<LinkedAcco
         LinkedAccountTO linkedAccountTO = 
LinkedAccountTO.class.cast(afterObject);
         return new CreateEvent(
                 linkedAccountTO.getConnObjectKeyValue(),
-                userTO,
+                model.getObject(),
                 target);
     }
 
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDirectoryPanelAditionalActionLinksProvider.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDirectoryPanelAditionalActionLinksProvider.java
index 9e5e120..012cf59 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDirectoryPanelAditionalActionLinksProvider.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDirectoryPanelAditionalActionLinksProvider.java
@@ -27,11 +27,12 @@ import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.PageReference;
+import org.apache.wicket.model.IModel;
 
 public interface AnyDirectoryPanelAditionalActionLinksProvider extends 
Serializable {
 
     List<Action<UserTO>> get(
-            UserTO modelObject,
+            IModel<UserTO> model,
             String realm,
             BaseModal<AnyWrapper<UserTO>> modal,
             String header,
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoAnyDirectoryPanelAditionalActionLinksProvider.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoAnyDirectoryPanelAditionalActionLinksProvider.java
index db90ec9..03e897e 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoAnyDirectoryPanelAditionalActionLinksProvider.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoAnyDirectoryPanelAditionalActionLinksProvider.java
@@ -26,6 +26,7 @@ import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.PageReference;
+import org.apache.wicket.model.IModel;
 
 public class IdRepoAnyDirectoryPanelAditionalActionLinksProvider
         implements AnyDirectoryPanelAditionalActionLinksProvider {
@@ -34,7 +35,7 @@ public class 
IdRepoAnyDirectoryPanelAditionalActionLinksProvider
 
     @Override
     public List<Action<UserTO>> get(
-            final UserTO modelObject,
+            final IModel<UserTO> model,
             final String realm,
             final BaseModal<AnyWrapper<UserTO>> modal,
             final String header,
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
index 9593000..0041eb5 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
@@ -239,7 +239,7 @@ public class UserDirectoryPanel extends 
AnyDirectoryPanel<UserTO, UserRestClient
             }
 
             
SyncopeWebApplication.get().getAnyDirectoryPanelAditionalActionLinksProvider().get(
-                    model.getObject(),
+                    model,
                     realm,
                     altDefaultModal,
                     getString("any.edit", new Model<>(new 
AnyWrapper<>(model.getObject()))),
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
index dd5288c..aadf84f 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
   <wicket:panel>
-    <span wicket:id="linkedAccountsList">[linkedAccountsList]</span>
-    <div wicket:id="toggle"/>
+    <span wicket:id="toggle"/>
+    <span wicket:id="mlpContainer">[MlpContainer]</span>
   </wicket:panel>
 </html>
\ No newline at end of file
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountsStatusModalPanel.html
similarity index 89%
copy from 
client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
copy to 
client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountsStatusModalPanel.html
index dd5288c..f6f3a66 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountsStatusModalPanel.html
@@ -18,7 +18,6 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
   <wicket:panel>
-    <span wicket:id="linkedAccountsList">[linkedAccountsList]</span>
-    <div wicket:id="toggle"/>
+    <div wicket:id="content"></div>
   </wicket:panel>
-</html>
\ No newline at end of file
+</html>
diff --git 
a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
 
b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
index ba2c522..2c9fd4b 100644
--- 
a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
+++ 
b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
@@ -267,7 +267,7 @@ public class ReconciliationLogic extends 
AbstractTransactionalLogic<EntityTO> {
                                         match.getLinkedAccount(),
                                         pushTask);
                                 if (result.getStatus() == 
ProvisioningReport.Status.FAILURE) {
-                                    
sce.getElements().add(results.get(0).getMessage());
+                                    sce.getElements().add(result.getMessage());
                                 } else {
                                     results.add(result);
                                 }

Reply via email to