You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2019/10/31 13:14:29 UTC
[syncope] branch 2_1_X updated: [SYNCOPE-1500] Allow single import
from External Resource (#137)
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/2_1_X by this push:
new d80301b [SYNCOPE-1500] Allow single import from External Resource (#137)
d80301b is described below
commit d80301b5ef40ae053d2cb245cf3ac8c5108e7f05
Author: Federico Palmitesta <fe...@gmail.com>
AuthorDate: Thu Oct 31 14:14:20 2019 +0100
[SYNCOPE-1500] Allow single import from External Resource (#137)
---
.../client/console/commons/status/StatusUtils.java | 4 +-
.../console/panels/ConnObjectListViewPanel.java | 87 ++++++++++++++++++++--
.../syncope/client/console/panels/ConnObjects.java | 27 +++++++
.../console/status/AnyStatusDirectoryPanel.java | 2 +
.../client/console/status/ReconTaskPanel.java | 52 +++++++++++--
.../status/ResourceStatusDirectoryPanel.java | 2 +
.../META-INF/resources/css/syncopeConsole.css | 6 +-
.../client/console/panels/ListViewPanel.html | 2 +-
.../client/console/status/ReconTaskPanel.html | 1 +
.../provisioning/java/utils/ConnObjectUtils.java | 8 +-
10 files changed, 175 insertions(+), 16 deletions(-)
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
index 14a98cc..4115ad0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
@@ -173,7 +173,7 @@ public final class StatusUtils implements Serializable {
case CREATED:
alt = "created icon";
title = "Created";
- clazz = Constants.UNDEFINED_ICON;
+ clazz = Constants.CREATED_ICON;
break;
case SUSPENDED:
@@ -235,7 +235,7 @@ public final class StatusUtils implements Serializable {
return getLabel(componentId, alt, title, clazz);
}
- private static Label getLabel(final String componentId, final String alt, final String title, final String clazz) {
+ public static Label getLabel(final String componentId, final String alt, final String title, final String clazz) {
return new Label(componentId, StringUtils.EMPTY) {
private static final long serialVersionUID = 4755868673082976208L;
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java
index bcff482..32925c4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java
@@ -18,6 +18,9 @@
*/
package org.apache.syncope.client.console.panels;
+import de.agilecoders.wicket.core.markup.html.bootstrap.components.PopoverBehavior;
+import de.agilecoders.wicket.core.markup.html.bootstrap.components.PopoverConfig;
+import de.agilecoders.wicket.core.markup.html.bootstrap.components.TooltipConfig;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
@@ -26,6 +29,8 @@ import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.console.commons.ConnIdSpecialName;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.status.StatusUtils;
import org.apache.syncope.client.console.panels.ListViewPanel.ListViewReload;
import org.apache.syncope.client.console.panels.search.AbstractSearchPanel;
import org.apache.syncope.client.console.panels.search.ConnObjectSearchPanel;
@@ -33,6 +38,7 @@ import org.apache.syncope.client.console.panels.search.SearchClause;
import org.apache.syncope.client.console.panels.search.SearchClausePanel;
import org.apache.syncope.client.console.panels.search.SearchUtils;
import org.apache.syncope.client.console.rest.AnyTypeRestClient;
+import org.apache.syncope.client.console.rest.ReconciliationRestClient;
import org.apache.syncope.client.console.rest.ResourceRestClient;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CollectionPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
@@ -41,10 +47,13 @@ import org.apache.syncope.common.lib.to.ConnObjectTO;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.tabs.Accordion;
import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.ReconStatus;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.MatchType;
import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.common.rest.api.beans.ConnObjectTOQuery;
+import org.apache.syncope.common.rest.api.beans.ReconQuery;
import org.apache.wicket.Component;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -68,8 +77,12 @@ public abstract class ConnObjectListViewPanel extends Panel {
private final AnyTypeRestClient anyTypeRestClient = new AnyTypeRestClient();
+ private final ReconciliationRestClient reconRestClient = new ReconciliationRestClient();
+
private static final int SIZE = 10;
+ private static final String STATUS = "Status";
+
private String nextPageCookie;
private AbstractSearchPanel searchPanel;
@@ -140,12 +153,42 @@ public abstract class ConnObjectListViewPanel extends Panel {
@Override
protected Component getValueComponent(final String key, final ConnObjectTO bean) {
- Optional<AttrTO> attrTO =
- bean.getAttrs().stream().filter(object -> object.getSchema().equals(key)).findAny();
-
- return !attrTO.isPresent() || attrTO.get().getValues().isEmpty()
- ? new Label("field", StringUtils.EMPTY)
- : new CollectionPanel("field", attrTO.get().getValues());
+ if (StringUtils.equals(key, STATUS)) {
+ ReconStatus status = reconRestClient.status(new ReconQuery.Builder(anyType, resource.getKey()).
+ connObjectKeyValue(bean.getAttr(ConnIdSpecialName.UID).get().getValues().get(0)).build());
+
+ return status.getOnSyncope() == null
+ ? StatusUtils.getLabel("field", "notfound icon", "Not found", Constants.NOT_FOUND_ICON)
+ : new Label("field", Model.of()).add(new PopoverBehavior(
+ Model.<String>of(),
+ Model.of(status.getAnyKey()),
+ new PopoverConfig().
+ withTitle(status.getMatchType() == MatchType.LINKED_ACCOUNT
+ ? MatchType.LINKED_ACCOUNT.name() + ", " + AnyTypeKind.USER
+ : status.getAnyTypeKind().name()).
+ withPlacement(TooltipConfig.Placement.left)) {
+
+ private static final long serialVersionUID = -7867802555691605021L;
+
+ @Override
+ protected String createRelAttribute() {
+ return "field";
+ }
+
+ @Override
+ public void onComponentTag(Component component, ComponentTag tag) {
+ super.onComponentTag(component, tag);
+ tag.put("class", Constants.ACTIVE_ICON);
+ }
+ });
+ } else {
+ Optional<AttrTO> attrTO =
+ bean.getAttrs().stream().filter(object -> object.getSchema().equals(key)).findAny();
+
+ return !attrTO.isPresent() || attrTO.get().getValues().isEmpty()
+ ? new Label("field", StringUtils.EMPTY)
+ : new CollectionPanel("field", attrTO.get().getValues());
+ }
}
};
@@ -167,6 +210,30 @@ public abstract class ConnObjectListViewPanel extends Panel {
withChecks(ListViewPanel.CheckAvailability.NONE).
setReuseItem(false);
+ if (!StringUtils.equals(anyType, SyncopeConstants.REALM_ANYTYPE)) {
+ builder.addAction(new ActionLink<ConnObjectTO>() {
+
+ private static final long serialVersionUID = 6377238742125L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final ConnObjectTO modelObject) {
+ String connObjectKeyValue = modelObject.getAttr(ConnIdSpecialName.UID).get().getValues().get(0);
+ String anyKey = reconRestClient.status(new ReconQuery.Builder(anyType, resource.getKey()).
+ connObjectKeyValue(connObjectKeyValue).build()).getAnyKey();
+
+ pullConnObject(
+ connObjectKeyValue,
+ target,
+ resource.getKey(),
+ anyType,
+ StringUtils.isNotBlank(anyKey),
+ pageRef);
+ }
+ }, ActionLink.ActionType.RECONCILIATION_PULL, StandardEntitlement.TASK_EXECUTE);
+
+ builder.includes(STATUS);
+ }
+
add(builder.build("objs"));
arrows = new WebMarkupContainer("arrows");
@@ -208,6 +275,14 @@ public abstract class ConnObjectListViewPanel extends Panel {
protected abstract void viewConnObject(ConnObjectTO connObjectTO, AjaxRequestTarget target);
+ protected abstract void pullConnObject(
+ String connObjectTO,
+ AjaxRequestTarget target,
+ String resource,
+ String anyType,
+ boolean isOnSyncope,
+ PageReference pageRef);
+
private List<ConnObjectTO> reloadItems(
final String resource,
final String anyType,
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
index 8f70d26a..2ccbd7a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
@@ -22,11 +22,13 @@ import java.util.List;
import java.util.stream.Collectors;
import org.apache.syncope.client.console.commons.Constants;
import org.apache.syncope.client.console.rest.AnyTypeRestClient;
+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.AjaxDropDownChoicePanel;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.ConnObjectTO;
import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.wicket.PageReference;
@@ -123,5 +125,30 @@ public class ConnObjects extends Panel implements ModalPanel {
target);
}
+ @Override
+ protected void pullConnObject(
+ final String connObjectKeyValue,
+ final AjaxRequestTarget target,
+ final String resource,
+ final String anyType,
+ final boolean isOnSyncope,
+ final PageReference pageRef) {
+ anyTypes.setEnabled(false);
+ target.add(anyTypes);
+
+ connObjects.next("PULL " + resource,
+ new ReconTaskPanel(
+ resource,
+ new PullTaskTO(),
+ anyType,
+ null,
+ connObjectKeyValue,
+ isOnSyncope,
+ connObjects,
+ pageRef),
+ target
+ );
+ }
+
}
}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
index b876f33..81438b4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
@@ -213,6 +213,7 @@ public class AnyStatusDirectoryPanel
new PushTaskTO(),
anyTO.getType(),
anyTO.getKey(),
+ true,
multiLevelPanelRef,
pageRef),
target);
@@ -233,6 +234,7 @@ public class AnyStatusDirectoryPanel
new PullTaskTO(),
anyTO.getType(),
anyTO.getKey(),
+ true,
multiLevelPanelRef,
pageRef),
target);
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
index fb778a6..0e4e4f3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
@@ -19,6 +19,7 @@
package org.apache.syncope.client.console.status;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
@@ -27,14 +28,17 @@ import org.apache.syncope.client.console.commons.Constants;
import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.panels.MultilevelPanel;
import org.apache.syncope.client.console.rest.ImplementationRestClient;
+import org.apache.syncope.client.console.rest.RealmRestClient;
import org.apache.syncope.client.console.rest.ReconciliationRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.EntityTO;
import org.apache.syncope.common.lib.to.ProvisioningTaskTO;
import org.apache.syncope.common.lib.to.PullTaskTO;
import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.types.ImplementationType;
import org.apache.syncope.common.lib.types.MatchingRule;
import org.apache.syncope.common.lib.types.UnmatchingRule;
@@ -42,6 +46,7 @@ import org.apache.syncope.common.rest.api.beans.ReconQuery;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
@@ -57,10 +62,12 @@ public class ReconTaskPanel extends MultilevelPanel.SecondLevel {
protected static final Logger LOG = LoggerFactory.getLogger(ReconTaskPanel.class);
- private final ReconciliationRestClient restClient = new ReconciliationRestClient();
-
private final ImplementationRestClient implRestClient = new ImplementationRestClient();
+ private final RealmRestClient realmRestClient = new RealmRestClient();
+
+ private final ReconciliationRestClient reconRestClient = new ReconciliationRestClient();
+
private final IModel<List<String>> pullActions = new LoadableDetachableModel<List<String>>() {
private static final long serialVersionUID = 5275935387613157437L;
@@ -88,12 +95,45 @@ public class ReconTaskPanel extends MultilevelPanel.SecondLevel {
final ProvisioningTaskTO taskTO,
final String anyType,
final String anyKey,
+ final boolean isOnSyncope,
+ final MultilevelPanel multiLevelPanelRef,
+ final PageReference pageRef) {
+ this(resource, taskTO, anyType, anyKey, null, isOnSyncope, multiLevelPanelRef, pageRef);
+ }
+
+ public ReconTaskPanel(
+ final String resource,
+ final ProvisioningTaskTO taskTO,
+ final String anyType,
+ final String anyKey,
+ final String connObjectKeyValue,
+ final boolean isOnSyncope,
final MultilevelPanel multiLevelPanelRef,
final PageReference pageRef) {
Form<ProvisioningTaskTO> form = new Form<>("form", new CompoundPropertyModel<>(taskTO));
add(form);
+ if (taskTO instanceof PushTaskTO) {
+ form.add(new Label("realm", ""));
+ } else {
+ AjaxDropDownChoicePanel<String> realm = new AjaxDropDownChoicePanel<>(
+ "realm", "destinationRealm", new PropertyModel<>(taskTO, "destinationRealm"), false);
+ form.add(realm);
+ realm.addRequiredLabel();
+ realm.setOutputMarkupId(true);
+
+ if (isOnSyncope) {
+ realm.getField().setModelObject(SyncopeConstants.ROOT_REALM);
+ realm.setVisible(false);
+ } else {
+ realm.setChoices(realmRestClient.list().stream().
+ sorted(Comparator.comparing(RealmTO::getName)).
+ map(RealmTO::getFullPath).
+ collect(Collectors.toList()));
+ }
+ }
+
AjaxPalettePanel<String> actions = new AjaxPalettePanel.Builder<String>().
setAllowMoveAll(true).setAllowOrder(true).
build("actions",
@@ -140,12 +180,14 @@ public class ReconTaskPanel extends MultilevelPanel.SecondLevel {
@Override
protected void onSubmit(final AjaxRequestTarget target) {
- ReconQuery reconQuery = new ReconQuery.Builder(anyType, resource).anyKey(anyKey).build();
+ ReconQuery reconQuery = new ReconQuery.Builder(anyType, resource).
+ anyKey(anyKey).
+ connObjectKeyValue(connObjectKeyValue).build();
try {
if (taskTO instanceof PushTaskTO) {
- restClient.push(reconQuery, (PushTaskTO) form.getModelObject());
+ reconRestClient.push(reconQuery, (PushTaskTO) form.getModelObject());
} else {
- restClient.pull(reconQuery, (PullTaskTO) form.getModelObject());
+ reconRestClient.pull(reconQuery, (PullTaskTO) form.getModelObject());
}
SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
index 217daea..410ace3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
@@ -141,6 +141,7 @@ public class ResourceStatusDirectoryPanel
new PushTaskTO(),
type,
bean.getKey(),
+ true,
multiLevelPanelRef,
pageRef),
target);
@@ -166,6 +167,7 @@ public class ResourceStatusDirectoryPanel
new PullTaskTO(),
type,
bean.getKey(),
+ true,
multiLevelPanelRef,
pageRef),
target);
diff --git a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index c2dcf2c..ee2fb5b 100644
--- a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -517,6 +517,10 @@ END - Style for Information panel
width: 110px !important;
}
+.table > tbody > tr > td.list_view_panel_labels {
+ vertical-align: middle;
+}
+
div.searchResult{
padding-top: 30px;
display: block;
@@ -880,7 +884,7 @@ li.todoitem a {
}
.popover{
- max-width: 100%;
+ max-width: 100%;
}
#popover:hover {
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ListViewPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ListViewPanel.html
index 2d3d7ee..400b2a0 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ListViewPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ListViewPanel.html
@@ -45,7 +45,7 @@ under the License.
<td id="check">
<input type="checkbox" wicket:id="check"/>
</td>
- <td wicket:id="fields" class="col_width"><span wicket:id="field"/></td>
+ <td wicket:id="fields" class="col_width list_view_panel_labels"><span wicket:id="field"/></td>
<td>
<div class="listview-actions">
<span wicket:id="actions">[actions]</span>
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/status/ReconTaskPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/status/ReconTaskPanel.html
index c0c4891..7ec28d6 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/status/ReconTaskPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/status/ReconTaskPanel.html
@@ -22,6 +22,7 @@ under the License.
<div class="form-group form-palette">
<span wicket:id="actions">[actions]</span>
</div>
+ <div class="form-group"><span wicket:id="realm">[realm]</span></div>
<div class="form-group"><span wicket:id="matchingRule">[matchingRule]</span></div>
<div class="form-group"><span wicket:id="unmatchingRule">[unmatchingRule]</span></div>
<div class="form-group"><span wicket:id="performCreate">[performCreate]</span></div>
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
index 064f477..17b4db6 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
@@ -37,6 +37,7 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
@@ -287,8 +288,11 @@ public class ConnObjectUtils {
default:
}
- // SYNCOPE-1343, remove null or empty values from the patch plain attributes
if (anyPatch != null) {
+ // ensure not to include incidental realm changes in the patch
+ anyPatch.setRealm(null);
+
+ // SYNCOPE-1343, remove null or empty values from the patch plain attributes
AnyOperations.cleanEmptyAttrs(updated, anyPatch);
}
return anyPatch;
@@ -299,6 +303,8 @@ public class ConnObjectUtils {
T anyTO = anyUtilsFactory.getInstance(provision.getAnyType().getKind()).newAnyTO();
anyTO.setType(provision.getAnyType().getKey());
+ anyTO.getAuxClasses().addAll(provision.getAuxClasses().stream().
+ map(AnyTypeClass::getKey).collect(Collectors.toList()));
// 1. fill with data from connector object
anyTO.setRealm(pullTask.getDestinatioRealm().getFullPath());