You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by sk...@apache.org on 2019/10/31 09:05:11 UTC
[syncope] branch 2_1_X updated: [SYNCOPE-957] Added new section in
Admin Console for the Multiaccount feature
This is an automated email from the ASF dual-hosted git repository.
skylark17 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 4f9e58d [SYNCOPE-957] Added new section in Admin Console for the Multiaccount feature
4f9e58d is described below
commit 4f9e58d3299d9b48502b8021cfce1b6445b45073
Author: Matteo Alessandroni <ma...@tirasa.net>
AuthorDate: Thu Oct 31 09:16:23 2019 +0100
[SYNCOPE-957] Added new section in Admin Console for the Multiaccount feature
---
.../syncope/client/console/commons/Constants.java | 2 +
.../console/panels/ConnObjectListViewPanel.java | 12 +-
.../panels/DisplayAttributesModalPanel.java | 8 +-
.../console/panels/LinkedAccountModalPanel.java | 232 +++++++++++
.../client/console/panels/ListViewPanel.java | 10 +-
.../client/console/panels/RealmDetails.java | 2 +-
.../client/console/panels/UserDirectoryPanel.java | 32 ++
.../client/console/rest/BaseRestClient.java | 2 +-
.../client/console/rest/ResourceRestClient.java | 16 +-
.../markup/html/form/AbstractFieldPanel.java | 2 +
.../markup/html/form/AbstractMultiPanel.java | 6 +
.../wicket/markup/html/form/ActionLink.java | 1 +
.../wicket/markup/html/form/AjaxPalettePanel.java | 6 +
.../markup/html/form/AjaxSpinnerFieldPanel.java | 15 +-
.../wicket/markup/html/form/BinaryFieldPanel.java | 8 +
.../client/console/wizards/AjaxWizardBuilder.java | 2 +-
.../client/console/wizards/any/AbstractAttrs.java | 147 +------
.../wizards/any/AbstractAttrsWizardStep.java | 455 +++++++++++++++++++++
.../client/console/wizards/any/AuxClasses.java | 2 +-
.../client/console/wizards/any/EntityWrapper.java | 38 ++
.../wizards/any/LinkedAccountCredentialsPanel.java | 125 ++++++
.../wizards/any/LinkedAccountDetailsPanel.java | 188 +++++++++
.../wizards/any/LinkedAccountPlainAttrsPanel.java | 254 ++++++++++++
.../wizards/any/LinkedAccountPrivilegesPanel.java | 66 +++
.../wizards/any/LinkedAccountWizardBuilder.java | 130 ++++++
.../client/console/wizards/any/PlainAttrs.java | 267 +-----------
.../wizards/any/TypeExtensionWizardBuilder.java | 2 +-
.../LinkedAccountModalPanel.html} | 6 +-
...operties => LinkedAccountModalPanel.properties} | 8 +-
...rties => LinkedAccountModalPanel_it.properties} | 8 +-
...rties => LinkedAccountModalPanel_ja.properties} | 8 +-
...es => LinkedAccountModalPanel_pt_BR.properties} | 8 +-
...rties => LinkedAccountModalPanel_ru.properties} | 8 +-
.../console/panels/UserDirectoryPanel.properties | 1 +
.../panels/UserDirectoryPanel_it.properties | 1 +
.../panels/UserDirectoryPanel_ja.properties | 1 +
.../panels/UserDirectoryPanel_pt_BR.properties | 1 +
.../panels/UserDirectoryPanel_ru.properties | 1 +
.../markup/html/form/ActionsPanel.properties | 4 +
.../markup/html/form/ActionsPanel_it.properties | 4 +
.../markup/html/form/ActionsPanel_ja.properties | 4 +
.../markup/html/form/ActionsPanel_pt_BR.properties | 4 +
.../markup/html/form/ActionsPanel_ru.properties | 4 +
.../client/console/wizards/any/AbstractAttrs.html | 9 +-
...s.html => AbstractAttrsWizardStep$Schemas.html} | 0
...ractAttrs.html => AbstractAttrsWizardStep.html} | 0
.../LinkedAccountCredentialsPanel.html} | 18 +-
.../any/LinkedAccountCredentialsPanel.properties} | 6 +-
.../LinkedAccountCredentialsPanel_it.properties} | 6 +-
.../LinkedAccountCredentialsPanel_ja.properties} | 6 +-
...LinkedAccountCredentialsPanel_pt_BR.properties} | 6 +-
.../LinkedAccountCredentialsPanel_ru.properties} | 6 +-
.../LinkedAccountDetailsPanel.html} | 18 +-
.../any/LinkedAccountDetailsPanel.properties} | 6 +-
.../any/LinkedAccountDetailsPanel_it.properties} | 6 +-
.../any/LinkedAccountDetailsPanel_ja.properties} | 6 +-
.../LinkedAccountDetailsPanel_pt_BR.properties} | 6 +-
.../any/LinkedAccountDetailsPanel_ru.properties} | 6 +-
...ttrs.html => LinkedAccountPlainAttrsPanel.html} | 9 +-
.../any/LinkedAccountPlainAttrsPanel.properties} | 4 +-
.../LinkedAccountPlainAttrsPanel_it.properties} | 4 +-
.../LinkedAccountPlainAttrsPanel_ja.properties} | 3 -
.../LinkedAccountPlainAttrsPanel_pt_BR.properties} | 3 -
.../LinkedAccountPlainAttrsPanel_ru.properties} | 3 -
.../LinkedAccountPrivilegesPanel.html} | 15 +-
.../any/LinkedAccountPrivilegesPanel.properties} | 4 +-
.../LinkedAccountPrivilegesPanel_it.properties} | 4 +-
.../LinkedAccountPrivilegesPanel_ja.properties} | 4 +-
.../LinkedAccountPrivilegesPanel_pt_BR.properties} | 4 +-
.../LinkedAccountPrivilegesPanel_ru.properties} | 4 +-
.../resources/ResourceConnCapabilitiesPanel.html | 2 +-
.../syncope/common/lib/to/LinkedAccountTO.java | 3 +-
.../lib/types/LinkedAccountPlainAttrProperty.java | 100 +++++
.../apache/syncope/fit/console/PoliciesITCase.java | 4 +-
.../apache/syncope/fit/console/UsersITCase.java | 2 +-
75 files changed, 1853 insertions(+), 525 deletions(-)
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
index ec1a759..e37f8e3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
@@ -57,6 +57,8 @@ public final class Constants {
public static final String ON_CHANGE = "change";
+ public static final String ON_KEYDOWN = "keydown";
+
public static final String ON_BLUR = "blur";
public static final String PNG_EXT = ".png";
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 d30ef2e..afafa69 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
@@ -33,6 +33,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.BaseRestClient;
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;
@@ -44,6 +45,7 @@ import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.syncope.common.rest.api.beans.ConnObjectTOQuery;
import org.apache.wicket.Component;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -213,12 +215,12 @@ public abstract class ConnObjectListViewPanel extends Panel {
final String cookie,
final String fiql) {
- Pair<String, List<ConnObjectTO>> items = new ResourceRestClient().listConnObjects(resource,
+ Pair<String, List<ConnObjectTO>> items = new ResourceRestClient().searchConnObjects(resource,
anyType,
- SIZE,
- cookie,
- new SortParam<>(ConnIdSpecialName.UID, true),
- fiql);
+ new ConnObjectTOQuery.Builder().
+ size(SIZE).
+ pagedResultsCookie(cookie).
+ orderBy(BaseRestClient.toOrderBy(new SortParam<>(ConnIdSpecialName.UID, true))).build());
nextPageCookie = items.getLeft();
return items.getRight();
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DisplayAttributesModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DisplayAttributesModalPanel.java
index 49dd601..efd6eb2 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/DisplayAttributesModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DisplayAttributesModalPanel.java
@@ -122,7 +122,7 @@ public abstract class DisplayAttributesModalPanel<T extends Serializable> extend
// remove old schemas from selected lists
selectedPlainSchemas.retainAll(pSchemaNames);
selectedDerSchemas.retainAll(dSchemaNames);
-
+
final WebMarkupContainer container = new WebMarkupContainer("container");
container.setOutputMarkupId(true);
add(container);
@@ -131,7 +131,7 @@ public abstract class DisplayAttributesModalPanel<T extends Serializable> extend
setAllowOrder(true).
setAllowMoveAll(true).
build("details",
- new PropertyModel<List<String>>(this, "selectedDetails"),
+ new PropertyModel<>(this, "selectedDetails"),
new ListModel<>(fnames.getObject()));
details.hideLabel();
details.setOutputMarkupId(true);
@@ -141,7 +141,7 @@ public abstract class DisplayAttributesModalPanel<T extends Serializable> extend
setAllowOrder(true).
setAllowMoveAll(true).
build("plainSchemas",
- new PropertyModel<List<String>>(this, "selectedPlainSchemas"),
+ new PropertyModel<>(this, "selectedPlainSchemas"),
new ListModel<>(psnames.getObject()));
plainSchemas.hideLabel();
plainSchemas.setOutputMarkupId(true);
@@ -151,7 +151,7 @@ public abstract class DisplayAttributesModalPanel<T extends Serializable> extend
setAllowOrder(true).
setAllowMoveAll(true).
build("derSchemas",
- new PropertyModel<List<String>>(this, "selectedDerSchemas"),
+ new PropertyModel<>(this, "selectedDerSchemas"),
new ListModel<>(dsnames.getObject()));
derSchemas.hideLabel();
derSchemas.setOutputMarkupId(true);
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
new file mode 100644
index 0000000..be0a70c
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
@@ -0,0 +1,232 @@
+/*
+ * 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 static org.apache.syncope.client.console.panels.AbstractModalPanel.LOG;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+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.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.AjaxWizard;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.any.LinkedAccountWizardBuilder;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.patch.LinkedAccountPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+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.model.Model;
+import org.apache.wicket.model.StringResourceModel;
+
+public class LinkedAccountModalPanel extends AbstractModalPanel<Serializable> {
+
+ private static final long serialVersionUID = -4603032036433309900L;
+
+ private final LinkedAccountWizardBuilder wizard;
+
+ private final WizardMgtPanel<LinkedAccountTO> list;
+
+ private final AjaxLink<LinkedAccountTO> addAjaxLink;
+
+ protected ActionLinksTogglePanel<LinkedAccountTO> actionTogglePanel;
+
+ private UserRestClient userRestClient = new UserRestClient();
+
+ private final List<LinkedAccountTO> linkedAccountTOs;
+
+ public LinkedAccountModalPanel(
+ final BaseModal<Serializable> modal,
+ final UserTO userTO,
+ final PageReference pageRef) {
+
+ super(modal, pageRef);
+
+ UserTO readUserTO = userRestClient.read(userTO.getKey());
+
+ setOutputMarkupId(true);
+
+ actionTogglePanel = new ActionLinksTogglePanel<>("toggle", pageRef);
+ add(actionTogglePanel);
+
+ wizard = new LinkedAccountWizardBuilder(readUserTO.getKey(), pageRef);
+
+ final ListViewPanel.Builder<LinkedAccountTO> builder = new ListViewPanel.Builder<LinkedAccountTO>(
+ LinkedAccountTO.class, pageRef) {
+
+ private static final long serialVersionUID = -5322423525438435153L;
+
+ @Override
+ protected LinkedAccountTO getActualItem(
+ final LinkedAccountTO item, final List<LinkedAccountTO> list) {
+
+ return item == null
+ ? null
+ : list.stream().filter(
+ in -> ((item.getKey() == null && in.getKey() == null)
+ || (in.getKey() != null && in.getKey().
+ equals(item.getKey())))).findAny().orElse(null);
+ }
+
+ @Override
+ protected void customActionCallback(final AjaxRequestTarget target) {
+ // change modal footer visibility
+ send(LinkedAccountModalPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
+ }
+
+ @Override
+ protected void customActionOnCancelCallback(final AjaxRequestTarget target) {
+ // change modal footer visibility
+ send(LinkedAccountModalPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void customActionOnFinishCallback(final AjaxRequestTarget target) {
+ checkAddButton();
+
+ linkedAccountTOs.clear();
+ linkedAccountTOs.addAll(userRestClient.read(userTO.getKey()).getLinkedAccounts());
+ sortLinkedAccounts();
+
+ ListViewPanel.class.cast(list).refreshList(linkedAccountTOs);
+
+ // change modal footer visibility
+ send(LinkedAccountModalPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
+ }
+
+ @Override
+ protected ActionLinksTogglePanel<LinkedAccountTO> getTogglePanel() {
+ return actionTogglePanel;
+ }
+ };
+
+ linkedAccountTOs = new ArrayList<>(readUserTO.getLinkedAccounts());
+ sortLinkedAccounts();
+
+ builder.setItems(linkedAccountTOs);
+ builder.includes("connObjectKeyValue", "resource", "suspended");
+ builder.setReuseItem(false);
+ builder.withChecks(ListViewPanel.CheckAvailability.NONE);
+
+ 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, StandardEntitlement.USER_READ).
+ addAction(new ActionLink<LinkedAccountTO>() {
+
+ private static final long serialVersionUID = 2555747430358755813L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final LinkedAccountTO linkedAccountTO) {
+ try {
+ LinkedAccountPatch linkedAccountPatch =
+ new LinkedAccountPatch.Builder().
+ operation(PatchOperation.DELETE).
+ linkedAccountTO(linkedAccountTO).build();
+ linkedAccountPatch.setLinkedAccountTO(linkedAccountTO);
+ UserPatch patch = new UserPatch();
+ 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();
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ send(LinkedAccountModalPanel.this, Broadcast.DEPTH, new ListViewPanel.ListViewReload<>(target));
+ }
+ }, ActionLink.ActionType.DELETE, StandardEntitlement.USER_UPDATE, true);
+
+ builder.addNewItemPanelBuilder(wizard);
+
+ list = builder.build("linkedAccountsList");
+ list.setOutputMarkupId(true);
+ list.setReadOnly(!SyncopeConsoleSession.get().owns(StandardEntitlement.USER_UPDATE));
+
+ addAjaxLink = new AjaxLink<LinkedAccountTO>("add") {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ send(LinkedAccountModalPanel.this, Broadcast.BREADTH,
+ new ActionLinksTogglePanel.ActionLinkToggleCloseEventPayload(target));
+
+ // this opens the wizard (set above) in CREATE mode
+ send(list, Broadcast.DEPTH, new AjaxWizard.NewItemActionEvent<>(new LinkedAccountTO(), target).
+ setResourceModel(new StringResourceModel("inner.create.linkedAccount",
+ LinkedAccountModalPanel.this)));
+ }
+ };
+ list.addOrReplaceInnerObject(addAjaxLink);
+ add(list);
+ }
+
+ private void sortLinkedAccounts() {
+ Collections.sort(linkedAccountTOs,
+ (o1, o2) -> AnyTypeRestClient.KEY_COMPARATOR.compare(
+ o1.getConnObjectKeyValue(), o2.getConnObjectKeyValue()));
+ }
+
+ private void checkAddButton() {
+ addAjaxLink.setVisible(SyncopeConsoleSession.get().owns(StandardEntitlement.USER_UPDATE));
+ }
+
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index 90580c8..661c65f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@ -201,7 +201,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
}
};
- beanItem.add(fields);
+ beanItem.add(fields.setOutputMarkupId(true));
if (togglePanel == null) {
beanItem.add(actions.clone("actions", new Model<>(bean)));
@@ -228,6 +228,14 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
};
}
+ /**
+ * Use this to refresh the ListView with updated items (e.g. from callback methods)
+ * @param elements
+ */
+ public void refreshList(final List<T> elements) {
+ beans.setList(elements);
+ }
+
public void setCheckAvailability(final CheckAvailability check) {
// used to perform selectable enabling check condition
this.check.setObject(check);
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
index 763422e..b1f7551 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
@@ -146,7 +146,7 @@ public class RealmDetails extends Panel {
AjaxPalettePanel<String> actions = new AjaxPalettePanel.Builder<String>().
setAllowMoveAll(true).setAllowOrder(true).
build("actions",
- new PropertyModel<List<String>>(realmTO, "actions"),
+ new PropertyModel<>(realmTO, "actions"),
new ListModel<>(logicActions.getObject()));
actions.setOutputMarkupId(true);
container.add(actions);
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
index 597a4f5..18db27c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.client.console.panels;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
@@ -32,6 +33,7 @@ import org.apache.syncope.client.console.rest.UserRestClient;
import org.apache.syncope.client.console.status.AnyStatusModal;
import org.apache.syncope.client.console.status.ChangePasswordModal;
import org.apache.syncope.client.console.tasks.AnyPropagationTasks;
+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.ActionLink.ActionType;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
@@ -59,6 +61,18 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
private static final long serialVersionUID = -1100228004207271270L;
+ protected final BaseModal<Serializable> wizardWrapperModal = new BaseModal<Serializable>("outer") {
+
+ private static final long serialVersionUID = 389935548143327858L;
+
+ @Override
+ protected void onConfigure() {
+ super.onConfigure();
+ setFooterVisible(false);
+ }
+
+ };
+
protected UserDirectoryPanel(final String id, final Builder builder) {
this(id, builder, true);
}
@@ -76,6 +90,9 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
modal.show(false);
}
});
+
+ wizardWrapperModal.size(Modal.Size.Large);
+ addOuterObject(wizardWrapperModal);
}
@Override
@@ -309,11 +326,26 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
target.add(utilityModal.setContent(
new NotificationTasks(AnyTypeKind.USER, model.getObject().getKey(), pageRef)));
+
utilityModal.header(new StringResourceModel("any.notification.tasks", model));
utilityModal.show(true);
target.add(utilityModal);
}
}, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST);
+
+ panel.add(new ActionLink<UserTO>() {
+
+ private static final long serialVersionUID = 8011039414597736111L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
+ target.add(wizardWrapperModal.setContent(
+ new LinkedAccountModalPanel(wizardWrapperModal, model.getObject(), pageRef)));
+ wizardWrapperModal.header(new ResourceModel("linkedAccounts.title"));
+ wizardWrapperModal.show(true);
+ }
+ }, ActionType.MANAGE_ACCOUNTS,
+ String.format("%s,%s", StandardEntitlement.USER_READ, StandardEntitlement.USER_UPDATE));
}
panel.add(new ActionLink<UserTO>() {
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java
index ecea2ae..1d259c0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java
@@ -55,7 +55,7 @@ public abstract class BaseRestClient implements RestClient {
SyncopeConsoleSession.get().resetClient(serviceClass);
}
- protected static String toOrderBy(final SortParam<String> sort) {
+ public static String toOrderBy(final SortParam<String> sort) {
OrderByClauseBuilder builder = SyncopeClient.getOrderByClauseBuilder();
String property = sort.getProperty();
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
index 8816444..d2ba042 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
@@ -29,7 +29,6 @@ import org.apache.syncope.common.lib.to.PagedConnObjectTOResult;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.rest.api.beans.ConnObjectTOQuery;
import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
/**
* Console client for invoking Rest Resources services.
@@ -56,26 +55,17 @@ public class ResourceRestClient extends BaseRestClient {
return getService(ResourceService.class).readConnObject(resource, anyTypeKey, anyKey);
}
- public Pair<String, List<ConnObjectTO>> listConnObjects(
+ public Pair<String, List<ConnObjectTO>> searchConnObjects(
final String resource,
final String anyTypeKey,
- final int size,
- final String pagedResultCookie,
- final SortParam<String> sort,
- final String fiql) {
-
- ConnObjectTOQuery.Builder builder = new ConnObjectTOQuery.Builder().
- pagedResultsCookie(pagedResultCookie).
- size(size).
- orderBy(toOrderBy(sort)).
- fiql(fiql);
+ final ConnObjectTOQuery query) {
final List<ConnObjectTO> result = new ArrayList<>();
String nextPageResultCookie = null;
PagedConnObjectTOResult list;
try {
- list = getService(ResourceService.class).searchConnObjects(resource, anyTypeKey, builder.build());
+ list = getService(ResourceService.class).searchConnObjects(resource, anyTypeKey, query);
result.addAll(list.getResult());
nextPageResultCookie = list.getPagedResultsCookie();
} catch (Exception e) {
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java
index dc23cc3..d19d2d3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java
@@ -122,4 +122,6 @@ public abstract class AbstractFieldPanel<T> extends Panel {
public String getName() {
return this.name;
}
+
+ public abstract AbstractFieldPanel<T> setReadOnly(boolean readOnly);
}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractMultiPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractMultiPanel.java
index 44dcfbd..20eba20 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractMultiPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractMultiPanel.java
@@ -200,8 +200,14 @@ public abstract class AbstractMultiPanel<INNER> extends AbstractFieldPanel<List<
// do nothing by default
}
+ @Override
public AbstractFieldPanel<List<INNER>> setReadOnly(final boolean readOnly) {
container.setEnabled(!readOnly);
return this;
}
+
+ public AbstractFieldPanel<List<INNER>> setFormReadOnly(final boolean readOnly) {
+ form.setEnabled(!readOnly);
+ return this;
+ }
}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
index c237bd4..d8dfba0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
@@ -93,6 +93,7 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
RECONCILIATION_PUSH("update"),
RECONCILIATION_PULL("update"),
MANAGE_RESOURCES("update"),
+ MANAGE_ACCOUNTS("update"),
MANAGE_USERS("update"),
MANAGE_GROUPS("update"),
PROPAGATION_TASKS("read"),
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.java
index 9423ce9..0f9e5c8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.java
@@ -200,6 +200,12 @@ public class AjaxPalettePanel<T extends Serializable> extends AbstractFieldPanel
target.add(palette);
}
+ @Override
+ public AbstractFieldPanel<List<T>> setReadOnly(final boolean readOnly) {
+ palette.setEnabled(!readOnly);
+ return this;
+ }
+
public static class Builder<T extends Serializable> implements Serializable {
private static final long serialVersionUID = 991248996001040352L;
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxSpinnerFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxSpinnerFieldPanel.java
index ea81daa..684cb8a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxSpinnerFieldPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxSpinnerFieldPanel.java
@@ -46,6 +46,8 @@ public final class AjaxSpinnerFieldPanel<T extends Number> extends FieldPanel<T>
private final Options options;
+ private SpinnerBehavior behavior;
+
private AjaxSpinnerFieldPanel(
final String id,
final String name,
@@ -62,7 +64,7 @@ public final class AjaxSpinnerFieldPanel<T extends Number> extends FieldPanel<T>
@Override
public JQueryUIBehavior newWidgetBehavior(final String selector) {
- SpinnerBehavior behavior = new SpinnerBehavior(selector, new SpinnerAdapter());
+ behavior = new SpinnerBehavior(selector, new SpinnerAdapter());
behavior.setOptions(options);
return behavior;
}
@@ -263,4 +265,15 @@ public final class AjaxSpinnerFieldPanel<T extends Number> extends FieldPanel<T>
}
}
+ @Override
+ public FieldPanel<T> setReadOnly(final boolean readOnly) {
+ super.setReadOnly(readOnly);
+ AjaxSpinner.class.cast(field).setEnabled(!readOnly);
+ options.set("disabled", readOnly);
+ if (behavior != null) {
+ behavior.setOptions(options);
+ }
+ return this;
+ }
+
}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
index 1a1ae2e..95e1dd6 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
@@ -291,4 +291,12 @@ public class BinaryFieldPanel extends FieldPanel<String> {
setVisibleFileButtons(StringUtils.isNotBlank(modelObj));
return this;
}
+
+ @Override
+ public FieldPanel<String> setReadOnly(final boolean readOnly) {
+ super.setReadOnly(readOnly);
+ fileUpload.setEnabled(!readOnly);
+ return this;
+ }
+
}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardBuilder.java
index d80962a..27d2c79 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardBuilder.java
@@ -90,7 +90,7 @@ public abstract class AjaxWizardBuilder<T extends Serializable> extends Abstract
// get the specified item if available
final T modelObject = newModelObject();
- return new AjaxWizard<T>(id, modelObject, buildModelSteps(modelObject, new WizardModel()), mode, this.pageRef) {
+ return new AjaxWizard<T>(id, modelObject, buildModelSteps(modelObject, new WizardModel()), mode, pageRef) {
private static final long serialVersionUID = 7770507663760640735L;
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java
index db39e61..40837db 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java
@@ -18,85 +18,47 @@
*/
package org.apache.syncope.client.console.wizards.any;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
-import org.apache.cxf.common.util.StringUtils;
-import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
import org.apache.syncope.client.console.rest.GroupRestClient;
-import org.apache.syncope.client.console.rest.SchemaRestClient;
-import org.apache.syncope.common.lib.to.SchemaTO;
-import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.client.console.wizards.AjaxWizard;
import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.SchemaTO;
import org.apache.syncope.common.lib.to.EntityTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.wicket.PageReference;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.core.util.lang.PropertyResolver;
-import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
-import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
-import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.util.ListModel;
-public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep implements ICondition {
+public abstract class AbstractAttrs<S extends SchemaTO> extends AbstractAttrsWizardStep<S> {
private static final long serialVersionUID = -5387344116983102292L;
- protected final Comparator<AttrTO> attrComparator = new AttrComparator();
-
- private final SchemaRestClient schemaRestClient = new SchemaRestClient();
-
- private final AnyTypeClassRestClient anyTypeClassRestClient = new AnyTypeClassRestClient();
-
private final GroupRestClient groupRestClient = new GroupRestClient();
- protected final AnyTO anyTO;
-
- private final List<String> whichAttrs;
-
- protected final Map<String, S> schemas = new LinkedHashMap<>();
-
- protected final Map<String, Map<String, S>> membershipSchemas = new LinkedHashMap<>();
-
- protected final IModel<List<AttrTO>> attrTOs;
-
protected final IModel<List<MembershipTO>> membershipTOs;
- private final List<String> anyTypeClasses;
+ protected final Map<String, Map<String, S>> membershipSchemas = new LinkedHashMap<>();
public AbstractAttrs(
final AnyWrapper<?> modelObject,
final List<String> anyTypeClasses,
final List<String> whichAttrs) {
- super();
- this.anyTypeClasses = anyTypeClasses;
- this.attrTOs = new ListModel<>(Collections.<AttrTO>emptyList());
- this.membershipTOs = new ListModel<>(Collections.<MembershipTO>emptyList());
- this.setOutputMarkupId(true);
+ super(modelObject.getInnerObject(), AjaxWizard.Mode.CREATE, anyTypeClasses, whichAttrs, null);
- this.anyTO = modelObject.getInnerObject();
- this.whichAttrs = whichAttrs;
- }
+ this.membershipTOs = new ListModel<>(Collections.<MembershipTO>emptyList());
- private List<AttrTO> loadAttrTOs() {
- List<String> classes = new ArrayList<>(anyTypeClasses);
- classes.addAll(anyTypeClassRestClient.list(anyTO.getAuxClasses()).stream().
- map(EntityTO::getKey).collect(Collectors.toList()));
- setSchemas(classes);
- setAttrs();
- return AbstractAttrs.this.getAttrsFromTO();
+ this.setOutputMarkupId(true);
}
@SuppressWarnings("unchecked")
@@ -127,12 +89,6 @@ public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep imple
return memberships;
}
- protected boolean reoderSchemas() {
- return !whichAttrs.isEmpty();
- }
-
- protected abstract SchemaType getSchemaType();
-
private void setSchemas(final String membership, final List<String> anyTypeClasses) {
final Map<String, S> mscs;
@@ -145,30 +101,18 @@ public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep imple
setSchemas(anyTypeClasses, mscs);
}
- private void setSchemas(final List<String> anyTypeClasses) {
- setSchemas(anyTypeClasses, schemas);
- }
-
- private void setSchemas(final List<String> anyTypeClasses, final Map<String, S> scs) {
- final List<S> allSchemas;
- if (anyTypeClasses.isEmpty()) {
- allSchemas = Collections.emptyList();
- } else {
- allSchemas = schemaRestClient.getSchemas(getSchemaType(), null, anyTypeClasses.toArray(new String[] {}));
+ private List<String> getMembershipAuxClasses(final MembershipTO membershipTO, final String anyType) {
+ try {
+ final GroupTO groupTO = groupRestClient.read(membershipTO.getGroupKey());
+ return groupTO.getTypeExtension(anyType).get().getAuxClasses();
+ } catch (Exception e) {
+ return Collections.emptyList();
}
+ }
- scs.clear();
-
- if (reoderSchemas()) {
- // 1. remove attributes not selected for display
- allSchemas.removeAll(allSchemas.stream().
- filter(schemaTO -> !whichAttrs.contains(schemaTO.getKey())).collect(Collectors.toSet()));
- }
+ protected abstract void setAttrs(MembershipTO membershipTO);
- allSchemas.forEach(schemaTO -> {
- scs.put(schemaTO.getKey(), schemaTO);
- });
- }
+ protected abstract List<AttrTO> getAttrsFromTO(MembershipTO membershipTO);
@Override
public void renderHead(final IHeaderResponse response) {
@@ -181,23 +125,6 @@ public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep imple
}
}
- protected abstract void setAttrs();
-
- protected abstract void setAttrs(MembershipTO membershipTO);
-
- protected abstract List<AttrTO> getAttrsFromTO();
-
- protected abstract List<AttrTO> getAttrsFromTO(MembershipTO membershipTO);
-
- protected List<String> getMembershipAuxClasses(final MembershipTO membershipTO, final String anyType) {
- try {
- final GroupTO groupTO = groupRestClient.read(membershipTO.getGroupKey());
- return groupTO.getTypeExtension(anyType).get().getAuxClasses();
- } catch (Exception e) {
- return Collections.emptyList();
- }
- }
-
@Override
public boolean evaluate() {
this.attrTOs.setObject(loadAttrTOs());
@@ -205,46 +132,4 @@ public abstract class AbstractAttrs<S extends SchemaTO> extends WizardStep imple
return !attrTOs.getObject().isEmpty() || !membershipTOs.getObject().isEmpty();
}
- public PageReference getPageReference() {
- // SYNCOPE-1213
- // default implementation does not require to pass page reference, override this method of want otherwise
- return null;
- }
-
- private class AttrComparator implements Comparator<AttrTO>, Serializable {
-
- private static final long serialVersionUID = -5105030477767941060L;
-
- @Override
- public int compare(final AttrTO left, final AttrTO right) {
- if (left == null || StringUtils.isEmpty(left.getSchema())) {
- return -1;
- }
- if (right == null || StringUtils.isEmpty(right.getSchema())) {
- return 1;
- } else if (AbstractAttrs.this.reoderSchemas()) {
- int leftIndex = AbstractAttrs.this.whichAttrs.indexOf(left.getSchema());
- int rightIndex = AbstractAttrs.this.whichAttrs.indexOf(right.getSchema());
-
- if (leftIndex > rightIndex) {
- return 1;
- } else if (leftIndex < rightIndex) {
- return -1;
- } else {
- return 0;
- }
- } else {
- return left.getSchema().compareTo(right.getSchema());
- }
- }
- }
-
- public class Schemas extends Panel {
-
- private static final long serialVersionUID = -2447602429647965090L;
-
- public Schemas(final String id) {
- super(id);
- }
- }
}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
new file mode 100644
index 0000000..1ed8cbe
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
@@ -0,0 +1,455 @@
+/*
+ * 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.wizards.any;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.ListUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.SchemaUtils;
+import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo;
+import org.apache.syncope.client.console.wicket.markup.html.form.AbstractFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDateFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDateTimeFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSpinnerFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.BinaryFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.EncryptedFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
+import org.apache.syncope.client.console.wizards.AjaxWizard;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.SchemaTO;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.markup.html.form.IChoiceRenderer;
+import org.apache.wicket.markup.html.list.ListItem;
+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.PropertyModel;
+import org.apache.wicket.model.util.ListModel;
+
+public abstract class AbstractAttrsWizardStep<S extends SchemaTO> extends WizardStep implements ICondition {
+
+ private static final long serialVersionUID = 8931397230194043674L;
+
+ protected final Comparator<AttrTO> attrComparator = new AttrComparator();
+
+ private final SchemaRestClient schemaRestClient = new SchemaRestClient();
+
+ protected final AnyTypeClassRestClient anyTypeClassRestClient = new AnyTypeClassRestClient();
+
+ protected final AnyTO anyTO;
+
+ protected AnyTO previousObject;
+
+ private final List<String> whichAttrs;
+
+ protected final Map<String, S> schemas = new LinkedHashMap<>();
+
+ protected final IModel<List<AttrTO>> attrTOs;
+
+ private final List<String> anyTypeClasses;
+
+ protected String fileKey = "";
+
+ protected final AjaxWizard.Mode mode;
+
+ public AbstractAttrsWizardStep(
+ final AnyTO anyTO,
+ final AjaxWizard.Mode mode,
+ final List<String> anyTypeClasses,
+ final List<String> whichAttrs,
+ final EntityWrapper<?> modelObject) {
+
+ super();
+ this.anyTypeClasses = anyTypeClasses;
+ this.attrTOs = new ListModel<>(Collections.<AttrTO>emptyList());
+
+ this.setOutputMarkupId(true);
+
+ this.mode = mode;
+ this.anyTO = anyTO;
+ this.whichAttrs = whichAttrs;
+ }
+
+ protected List<AttrTO> loadAttrTOs() {
+ List<String> classes = new ArrayList<>(anyTypeClasses);
+ classes.addAll(anyTypeClassRestClient.list(anyTO.getAuxClasses()).stream().
+ map(EntityTO::getKey).collect(Collectors.toList()));
+ setSchemas(classes);
+ setAttrs();
+ return AbstractAttrsWizardStep.this.getAttrsFromTO();
+ }
+
+ protected boolean reoderSchemas() {
+ return !whichAttrs.isEmpty();
+ }
+
+ protected abstract SchemaType getSchemaType();
+
+ private void setSchemas(final List<String> anyTypeClasses) {
+ setSchemas(anyTypeClasses, schemas);
+ }
+
+ protected void setSchemas(final List<String> anyTypeClasses, final Map<String, S> scs) {
+ final List<S> allSchemas;
+ if (anyTypeClasses.isEmpty()) {
+ allSchemas = Collections.emptyList();
+ } else {
+ allSchemas = schemaRestClient.getSchemas(getSchemaType(), null, anyTypeClasses.toArray(new String[] {}));
+ }
+
+ scs.clear();
+
+ if (reoderSchemas()) {
+ // 1. remove attributes not selected for display
+ allSchemas.removeAll(allSchemas.stream().
+ filter(schemaTO -> !whichAttrs.contains(schemaTO.getKey())).collect(Collectors.toSet()));
+ }
+
+ allSchemas.forEach(schemaTO -> {
+ scs.put(schemaTO.getKey(), schemaTO);
+ });
+ }
+
+ @Override
+ public void renderHead(final IHeaderResponse response) {
+ super.renderHead(response);
+ if (CollectionUtils.isEmpty(attrTOs.getObject())) {
+ response.render(OnDomReadyHeaderItem.forScript(
+ String.format("$('#emptyPlaceholder').append(\"%s\"); $('#attributes').hide();",
+ getString("attribute.empty.list"))));
+ }
+ }
+
+ protected abstract void setAttrs();
+
+ protected abstract List<AttrTO> getAttrsFromTO();
+
+ @Override
+ public boolean evaluate() {
+ this.attrTOs.setObject(loadAttrTOs());
+ return !attrTOs.getObject().isEmpty();
+ }
+
+ public PageReference getPageReference() {
+ // SYNCOPE-1213
+ // default implementation does not require to pass page reference, override this method of want otherwise
+ return null;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected FieldPanel getFieldPanel(final PlainSchemaTO schemaTO) {
+ final boolean required;
+ final boolean readOnly;
+ final AttrSchemaType type;
+ final boolean jexlHelp;
+
+ if (mode == AjaxWizard.Mode.TEMPLATE) {
+ required = false;
+ readOnly = false;
+ type = AttrSchemaType.String;
+ jexlHelp = true;
+ } else {
+ required = schemaTO.getMandatoryCondition().equalsIgnoreCase("true");
+ readOnly = schemaTO.isReadonly();
+ type = schemaTO.getType();
+ jexlHelp = false;
+ }
+
+ FieldPanel panel;
+ switch (type) {
+ case Boolean:
+ panel = new AjaxCheckBoxPanel(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ new Model<>(),
+ true);
+ panel.setRequired(required);
+ break;
+
+ case Date:
+ String datePattern = schemaTO.getConversionPattern() == null
+ ? SyncopeConstants.DEFAULT_DATE_PATTERN
+ : schemaTO.getConversionPattern();
+
+ if (datePattern.contains("H")) {
+ panel = new AjaxDateTimeFieldPanel(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ new Model<>(),
+ datePattern);
+ } else {
+ panel = new AjaxDateFieldPanel(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ new Model<>(),
+ datePattern);
+ }
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+
+ break;
+
+ case Enum:
+ panel = new AjaxDropDownChoicePanel<>("panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+ ((AjaxDropDownChoicePanel<String>) panel).setChoices(SchemaUtils.getEnumeratedValues(schemaTO));
+
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(schemaTO.getEnumerationKeys())) {
+ ((AjaxDropDownChoicePanel) panel).setChoiceRenderer(new IChoiceRenderer<String>() {
+
+ private static final long serialVersionUID = -3724971416312135885L;
+
+ private final Map<String, String> valueMap = SchemaUtils.getEnumeratedKeyValues(schemaTO);
+
+ @Override
+ public String getDisplayValue(final String value) {
+ return valueMap.get(value) == null ? value : valueMap.get(value);
+ }
+
+ @Override
+ public String getIdValue(final String value, final int i) {
+ return value;
+ }
+
+ @Override
+ public String getObject(
+ final String id, final IModel<? extends List<? extends String>> choices) {
+ return id;
+ }
+ });
+ }
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ case Long:
+ panel = new AjaxSpinnerFieldPanel.Builder<Long>().enableOnChange().build(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ Long.class,
+ new Model<>());
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ case Double:
+ panel = new AjaxSpinnerFieldPanel.Builder<Double>().enableOnChange().step(0.1).build(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ Double.class,
+ new Model<>());
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ case Binary:
+ final PageReference pageRef = getPageReference();
+ panel = new BinaryFieldPanel(
+ "panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
+ new Model<>(),
+ schemaTO.getMimeType(),
+ fileKey) {
+
+ private static final long serialVersionUID = -3268213909514986831L;
+
+ @Override
+ protected PageReference getPageReference() {
+ return pageRef;
+ }
+
+ };
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ case Encrypted:
+ panel = new EncryptedFieldPanel("panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ break;
+
+ default:
+ panel = new AjaxTextFieldPanel("panel",
+ schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+
+ if (jexlHelp) {
+ AjaxTextFieldPanel.class.cast(panel).enableJexlHelp();
+ }
+
+ if (required) {
+ panel.addRequiredLabel();
+ }
+ }
+
+ panel.setReadOnly(readOnly);
+
+ return panel;
+ }
+
+ private class AttrComparator implements Comparator<AttrTO>, Serializable {
+
+ private static final long serialVersionUID = -5105030477767941060L;
+
+ @Override
+ public int compare(final AttrTO left, final AttrTO right) {
+ if (left == null || StringUtils.isEmpty(left.getSchema())) {
+ return -1;
+ }
+ if (right == null || StringUtils.isEmpty(right.getSchema())) {
+ return 1;
+ } else if (AbstractAttrsWizardStep.this.reoderSchemas()) {
+ int leftIndex = AbstractAttrsWizardStep.this.whichAttrs.indexOf(left.getSchema());
+ int rightIndex = AbstractAttrsWizardStep.this.whichAttrs.indexOf(right.getSchema());
+
+ if (leftIndex > rightIndex) {
+ return 1;
+ } else if (leftIndex < rightIndex) {
+ return -1;
+ } else {
+ return 0;
+ }
+ } else {
+ return left.getSchema().compareTo(right.getSchema());
+ }
+ }
+ }
+
+ protected FormComponent<?> checkboxToggle(
+ final AttrTO attrTO,
+ final AbstractFieldPanel<?> panel,
+ final boolean isMultivalue) {
+
+ // do nothing
+ return null;
+ }
+
+ public class Schemas extends Panel {
+
+ private static final long serialVersionUID = -2447602429647965090L;
+
+ public Schemas(final String id) {
+ super(id);
+ }
+ }
+
+ protected abstract class PlainSchemas<T> extends Schemas {
+
+ private static final long serialVersionUID = 8315035592714180404L;
+
+ public PlainSchemas(
+ final String id,
+ final Map<String, PlainSchemaTO> schemas,
+ final IModel<T> attrTOs) {
+
+ super(id);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ protected AbstractFieldPanel<?> setPanel(
+ final Map<String, PlainSchemaTO> schemas,
+ final ListItem<AttrTO> item,
+ final boolean setReadOnly) {
+
+ AttrTO attrTO = item.getModelObject();
+ final boolean isMultivalue = mode != AjaxWizard.Mode.TEMPLATE
+ && schemas.get(attrTO.getSchema()).isMultivalue();
+
+ AbstractFieldPanel<?> panel = getFieldPanel(schemas.get(attrTO.getSchema()));
+ if (isMultivalue) {
+ // SYNCOPE-1476 set form as multipart to properly manage membership attributes
+ panel = new MultiFieldPanel.Builder<>(
+ new PropertyModel<>(attrTO, "values")).build(
+ "panel",
+ attrTO.getSchema(),
+ FieldPanel.class.cast(panel)).setFormAsMultipart(true);
+ // SYNCOPE-1215 the entire multifield panel must be readonly, not only its field
+ MultiFieldPanel.class.cast(panel).setReadOnly(schemas.get(attrTO.getSchema()).isReadonly());
+ MultiFieldPanel.class.cast(panel).setFormReadOnly(setReadOnly);
+ } else {
+ FieldPanel.class.cast(panel).setNewModel(attrTO.getValues()).setReadOnly(setReadOnly);
+ }
+ item.add(panel);
+
+ setExternalAction(attrTO, panel);
+
+ return panel;
+ }
+
+ protected void setExternalAction(final AttrTO attrTO, final AbstractFieldPanel<?> panel) {
+ Optional<AttrTO> prevAttr = previousObject == null
+ ? Optional.empty()
+ : previousObject.getPlainAttr(attrTO.getSchema());
+ if (previousObject != null
+ && ((!prevAttr.isPresent() && attrTO.getValues().stream().anyMatch(
+ org.apache.commons.lang3.StringUtils::isNotBlank))
+ || (prevAttr.isPresent() && !ListUtils.isEqualList(
+ prevAttr.get().getValues().stream().
+ filter(org.apache.commons.lang3.StringUtils::isNotBlank).collect(Collectors.toList()),
+ attrTO.getValues().stream().
+ filter(org.apache.commons.lang3.StringUtils::isNotBlank).collect(Collectors.toList()))))) {
+
+ List<String> oldValues = prevAttr.isPresent()
+ ? prevAttr.get().getValues()
+ : Collections.<String>emptyList();
+ panel.showExternAction(new LabelInfo("externalAction", oldValues));
+ }
+ }
+ }
+
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java
index d0f8ac9..7729425 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java
@@ -51,7 +51,7 @@ public class AuxClasses extends WizardStep {
}
Collections.sort(choices);
add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).build("auxClasses",
- new PropertyModel<List<String>>(modelObject.getInnerObject(), "auxClasses"),
+ new PropertyModel<>(modelObject.getInnerObject(), "auxClasses"),
new ListModel<>(choices)).hideLabel().setOutputMarkupId(true));
// ------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/EntityWrapper.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/EntityWrapper.java
new file mode 100644
index 0000000..4200b35
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/EntityWrapper.java
@@ -0,0 +1,38 @@
+/*
+ * 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.wizards.any;
+
+import java.io.Serializable;
+import org.apache.syncope.common.lib.BaseBean;
+
+public class EntityWrapper<T extends BaseBean> implements Serializable {
+
+ private static final long serialVersionUID = -187286422128231810L;
+
+ protected final T entityTO;
+
+ public EntityWrapper(final T entityTO) {
+ this.entityTO = entityTO;
+ }
+
+ public T getInnerObject() {
+ return entityTO;
+ }
+
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
new file mode 100644
index 0000000..959fb38
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
@@ -0,0 +1,125 @@
+/*
+ * 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.wizards.any;
+
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggle;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPasswordFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.types.LinkedAccountPlainAttrProperty;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.form.CheckBox;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.markup.html.form.PasswordTextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+
+public class LinkedAccountCredentialsPanel extends WizardStep {
+
+ private static final long serialVersionUID = 5116461957402341603L;
+
+ public LinkedAccountCredentialsPanel(final LinkedAccountTO linkedAccountTO) {
+ super();
+ setOutputMarkupId(true);
+
+ AjaxTextFieldPanel usernameField = new AjaxTextFieldPanel(
+ "username",
+ "username",
+ new PropertyModel<>(linkedAccountTO, "username"),
+ false);
+ usernameField.setOutputMarkupId(true);
+ FieldPanel.class.cast(usernameField).setReadOnly(true);
+ LinkedAccountPlainAttrProperty property = new LinkedAccountPlainAttrProperty();
+ property.setOverridable(false);
+ property.setSchema("username");
+ property.getValues().add(linkedAccountTO.getUsername());
+ usernameField.showExternAction(checkboxToggle(property, usernameField));
+ add(usernameField);
+
+ AjaxPasswordFieldPanel passwordField = new AjaxPasswordFieldPanel(
+ "password",
+ "password",
+ new PropertyModel<>(linkedAccountTO, "password"));
+ passwordField.setOutputMarkupId(true);
+ passwordField.setRequired(true);
+ passwordField.setMarkupId("password");
+ FieldPanel.class.cast(passwordField).setReadOnly(true);
+ property = new LinkedAccountPlainAttrProperty();
+ property.setOverridable(false);
+ property.setSchema("password");
+ property.getValues().add(linkedAccountTO.getPassword());
+ passwordField.showExternAction(checkboxToggle(property, passwordField));
+ ((PasswordTextField) passwordField.getField()).setResetPassword(true);
+ add(passwordField);
+ }
+
+ private FormComponent<?> checkboxToggle(
+ final LinkedAccountPlainAttrProperty property, final FieldPanel<?> panel) {
+
+ final BootstrapToggleConfig config = new BootstrapToggleConfig().
+ withOnStyle(BootstrapToggleConfig.Style.success).
+ withOffStyle(BootstrapToggleConfig.Style.danger).
+ withSize(BootstrapToggleConfig.Size.mini);
+
+ return new BootstrapToggle("externalAction", new PropertyModel<Boolean>(property, "overridable"), config) {
+
+ private static final long serialVersionUID = -875219845189261873L;
+
+ @Override
+ protected CheckBox newCheckBox(final String id, final IModel<Boolean> model) {
+ final CheckBox checkBox = super.newCheckBox(id, model);
+ checkBox.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ panel.setReadOnly(!model.getObject());
+ target.add(panel);
+ }
+ });
+ return checkBox;
+ }
+
+ @Override
+ protected IModel<String> getOnLabel() {
+ return Model.of("Override");
+ }
+
+ @Override
+ protected IModel<String> getOffLabel() {
+ return Model.of("Override?");
+ }
+
+ @Override
+ protected void onComponentTag(final ComponentTag tag) {
+ super.onComponentTag(tag);
+ tag.append("class", "overridable", " ");
+ }
+ };
+ }
+
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
new file mode 100644
index 0000000..e9fc994
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
@@ -0,0 +1,188 @@
+/*
+ * 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.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;
+import org.apache.syncope.client.console.commons.ConnIdSpecialName;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.rest.ResourceRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.rest.api.beans.ConnObjectTOQuery;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxEventBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxCallListener;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.attributes.ThrottlingSettings;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LinkedAccountDetailsPanel extends WizardStep {
+
+ private static final long serialVersionUID = 1221037007528732347L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(LinkedAccountDetailsPanel.class);
+
+ private final ResourceRestClient resourceRestClient = new ResourceRestClient();
+
+ private ArrayList<String> connObjectKeyFieldValues;
+
+ public LinkedAccountDetailsPanel(final LinkedAccountTO linkedAccountTO) {
+ super();
+ setOutputMarkupId(true);
+
+ AjaxDropDownChoicePanel<String> dropdownResourceField = new AjaxDropDownChoicePanel<>(
+ "resource",
+ "resource",
+ new PropertyModel<>(linkedAccountTO, "resource"),
+ false);
+ dropdownResourceField.setChoices(resourceRestClient.list().stream().
+ filter(resource -> resource.getProvision(AnyTypeKind.USER.name()).isPresent()
+ && resource.getProvision(AnyTypeKind.USER.name()).get().getMapping() != null
+ && !resource.getProvision(AnyTypeKind.USER.name()).get().getMapping().getItems().isEmpty()).
+ map(resource -> resource.getKey()).
+ collect(Collectors.toList()));
+ dropdownResourceField.setOutputMarkupId(true);
+ dropdownResourceField.addRequiredLabel();
+ dropdownResourceField.setNullValid(false);
+ dropdownResourceField.setRequired(true);
+ add(dropdownResourceField);
+
+ final String connObjectKeyFieldId = "connObjectKeyValue";
+ AjaxTextFieldPanel connObjectKeyField = new AjaxTextFieldPanel(
+ "connObjectKeyValue",
+ "connObjectKeyValue",
+ new PropertyModel<>(linkedAccountTO, "connObjectKeyValue"),
+ false);
+ connObjectKeyField.setOutputMarkupId(true);
+ connObjectKeyField.addRequiredLabel();
+ connObjectKeyField.setChoices(Collections.<String>emptyList());
+ connObjectKeyField.setEnabled(false);
+ add(connObjectKeyField);
+
+ dropdownResourceField.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ boolean enabled = dropdownResourceField.getModelObject() != null
+ && !dropdownResourceField.getModelObject().isEmpty();
+ connObjectKeyField.setEnabled(enabled);
+ if (enabled) {
+ setConnObjectFieldChoices(connObjectKeyField, dropdownResourceField.getModelObject(), null);
+ }
+ target.add(connObjectKeyField);
+ }
+ });
+
+ connObjectKeyField.getField().setMarkupId(connObjectKeyFieldId);
+ connObjectKeyField.getField().add(new AjaxEventBehavior(Constants.ON_KEYDOWN) {
+
+ private static final long serialVersionUID = 3533589614190959822L;
+
+ @Override
+ protected void onEvent(final AjaxRequestTarget target) {
+ String searchTerm = connObjectKeyField.getField().getInput();
+ if (StringUtils.isNotBlank(searchTerm) && searchTerm.length() > 1) {
+ setConnObjectFieldChoices(connObjectKeyField, dropdownResourceField.getModelObject(), searchTerm);
+
+ // If elements are found, send an "arrow down" key event to open input autocomplete dropdown
+ target.appendJavaScript(connObjectKeyFieldValues.isEmpty()
+ ? "$('#" + connObjectKeyFieldId + "-autocomplete-container').hide();"
+ : "var simulatedEvent = new KeyboardEvent('keydown', {keyCode: 40, which: 40}); "
+ + "document.getElementById('" + connObjectKeyFieldId + "').dispatchEvent(simulatedEvent);");
+ }
+ }
+
+ @Override
+ protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+ super.updateAjaxAttributes(attributes);
+
+ AjaxCallListener listener = new AjaxCallListener() {
+
+ private static final long serialVersionUID = 2208168001920794667L;
+
+ @Override
+ public CharSequence getPrecondition(final Component component) {
+ // Eevaluates weather an ajax call will be executed or not.
+ // If the key code is "arrow down" or "arrow up" do NOT trigger the event callback
+ return "var keycode = Wicket.Event.keyCode(attrs.event); "
+ + "if ((keycode == 40) || (keycode == 38)) {return false;} return true;";
+ }
+ };
+ attributes.getAjaxCallListeners().add(listener);
+ attributes.setThrottlingSettings(new ThrottlingSettings("id", Duration.seconds(1.2), true));
+ }
+ });
+ }
+
+ private void setConnObjectFieldChoices(
+ final AjaxTextFieldPanel ajaxTextFieldPanel,
+ final String resource,
+ final String searchTerm) {
+
+ Set<String> choices = new HashSet<>();
+ String resourceRemoteKey = ConnIdSpecialName.NAME;
+ try {
+ resourceRemoteKey = resourceRestClient.read(resource).getProvision(AnyTypeKind.USER.name()).get().
+ getMapping().getConnObjectKeyItem().getExtAttrName();
+ } catch (Exception ex) {
+ LOG.error("While reading mapping for resource {}", resource, ex);
+ }
+
+ ConnObjectTOQuery.Builder builder = new ConnObjectTOQuery.Builder().
+ size(2).
+ orderBy(BaseRestClient.toOrderBy(new SortParam<>(resourceRemoteKey, true)));
+ if (StringUtils.isNotBlank(searchTerm)) {
+ builder.fiql(SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
+ is(resourceRemoteKey).equalTo(searchTerm + "*").query()).build();
+ }
+ Pair<String, List<ConnObjectTO>> items = resourceRestClient.searchConnObjects(resource,
+ AnyTypeKind.USER.name(),
+ builder.build());
+
+ 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);
+ ajaxTextFieldPanel.setChoices(connObjectKeyFieldValues);
+ }
+
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
new file mode 100644
index 0000000..40a7f1d
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
@@ -0,0 +1,254 @@
+/*
+ * 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.wizards.any;
+
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggle;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.layout.FormLayoutInfoUtils;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
+import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.tabs.Accordion;
+import org.apache.syncope.client.console.wicket.markup.html.form.AbstractFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
+import org.apache.syncope.client.console.wizards.AjaxWizard;
+import org.apache.syncope.common.lib.EntityTOUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.LinkedAccountPlainAttrProperty;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.CheckBox;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+
+public class LinkedAccountPlainAttrsPanel extends AbstractAttrsWizardStep<PlainSchemaTO> {
+
+ private static final long serialVersionUID = -6664931684253730934L;
+
+ private final LinkedAccountTO linkedAccountTO;
+
+ private final UserTO userTO;
+
+ private final Set<AttrTO> fixedAttrs = new HashSet<>();
+
+ private final List<LinkedAccountPlainAttrProperty> accountPlainAttrProperties = new ArrayList<>();
+
+ public <T extends AnyTO> LinkedAccountPlainAttrsPanel(
+ final EntityWrapper<LinkedAccountTO> modelObject,
+ final UserTO userTO) throws IllegalArgumentException {
+
+ super(userTO,
+ AjaxWizard.Mode.EDIT,
+ new AnyTypeRestClient().read(userTO.getType()).getClasses(),
+ FormLayoutInfoUtils.fetch(Arrays.asList(userTO.getType())).getLeft().getWhichPlainAttrs(),
+ modelObject);
+
+ this.linkedAccountTO = modelObject.getInnerObject();
+ this.fixedAttrs.addAll(this.linkedAccountTO.getPlainAttrs());
+ this.userTO = userTO;
+
+ add(new Accordion("plainSchemas", Collections.<ITab>singletonList(new AbstractTab(
+ new ResourceModel("attributes.accordion", "Plain Attributes")) {
+
+ private static final long serialVersionUID = -7078941093668723016L;
+
+ @Override
+ public WebMarkupContainer getPanel(final String panelId) {
+ return new PlainSchemasOwn(panelId, schemas, attrTOs);
+ }
+ }), Model.of(0)).setOutputMarkupId(true));
+ }
+
+ @Override
+ protected FormComponent<?> checkboxToggle(
+ final AttrTO attrTO,
+ final AbstractFieldPanel<?> panel,
+ final boolean isMultivalue) {
+
+ LinkedAccountPlainAttrProperty property = accountPlainAttrProperties.stream().filter(
+ existingProperty -> {
+ return existingProperty.getSchema().equals(attrTO.getSchema());
+ }).findFirst().orElseGet(() -> {
+ LinkedAccountPlainAttrProperty newProperty = new LinkedAccountPlainAttrProperty();
+ newProperty.setOverridable(linkedAccountTO.getPlainAttr(attrTO.getSchema()).isPresent());
+ newProperty.setSchema(attrTO.getSchema());
+ newProperty.getValues().addAll(attrTO.getValues());
+ accountPlainAttrProperties.add(newProperty);
+ return newProperty;
+ });
+
+ final BootstrapToggleConfig config = new BootstrapToggleConfig().
+ withOnStyle(BootstrapToggleConfig.Style.success).
+ withOffStyle(BootstrapToggleConfig.Style.danger).
+ withSize(BootstrapToggleConfig.Size.mini);
+
+ return new BootstrapToggle("externalAction", new PropertyModel<Boolean>(property, "overridable"), config) {
+
+ private static final long serialVersionUID = -875219845189261873L;
+
+ @Override
+ protected CheckBox newCheckBox(final String id, final IModel<Boolean> model) {
+ final CheckBox checkBox = super.newCheckBox(id, model);
+ checkBox.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ if (isMultivalue) {
+ MultiFieldPanel.class.cast(panel).setFormReadOnly(!model.getObject());
+ } else {
+ FieldPanel.class.cast(panel).setReadOnly(!model.getObject());
+ }
+
+ updateAccountPlainSchemas(property, model.getObject());
+ target.add(panel);
+ }
+ });
+ return checkBox;
+ }
+
+ @Override
+ protected IModel<String> getOnLabel() {
+ return Model.of("Override");
+ }
+
+ @Override
+ protected IModel<String> getOffLabel() {
+ return Model.of("Override?");
+ }
+
+ @Override
+ protected void onComponentTag(final ComponentTag tag) {
+ super.onComponentTag(tag);
+ tag.append("class", "overridable", " ");
+ }
+ };
+ }
+
+ private void updateAccountPlainSchemas(final LinkedAccountPlainAttrProperty property, final Boolean modelObject) {
+ Set<AttrTO> withoutCurrentSChema = new HashSet<>(linkedAccountTO.getPlainAttrs().stream().
+ filter(attr -> !attr.getSchema().equals(property.getSchema())).
+ collect(Collectors.toSet()));
+ linkedAccountTO.getPlainAttrs().clear();
+ linkedAccountTO.getPlainAttrs().addAll(withoutCurrentSChema);
+ if (modelObject) {
+ linkedAccountTO.getPlainAttrs().add(
+ fixedAttrs.stream().filter(attrTO -> attrTO.getSchema().equals(property.getSchema())).findFirst().
+ orElseGet(() -> new AttrTO.Builder().
+ schema(property.getSchema()).values(property.getValues()).build()));
+ }
+ }
+
+ @Override
+ protected SchemaType getSchemaType() {
+ return SchemaType.PLAIN;
+ }
+
+ @Override
+ protected void setAttrs() {
+ List<AttrTO> attrs = new ArrayList<>();
+ setFixedAttr(schemas.values());
+ Map<String, AttrTO> attrMap = EntityTOUtils.buildAttrMap(fixedAttrs);
+
+ attrs.addAll(schemas.values().stream().map(schema -> {
+ AttrTO attrTO = new AttrTO();
+ attrTO.setSchema(schema.getKey());
+ if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) {
+ attrTO.getValues().add("");
+ } else {
+ attrTO = attrMap.get(schema.getKey());
+ }
+ return attrTO;
+ }).collect(Collectors.toList()));
+
+ fixedAttrs.clear();
+ fixedAttrs.addAll(attrs);
+ }
+
+ @Override
+ protected List<AttrTO> getAttrsFromTO() {
+ return fixedAttrs.stream().sorted(attrComparator).collect(Collectors.toList());
+ }
+
+ private void setFixedAttr(final Collection<PlainSchemaTO> values) {
+ values.forEach(schema -> {
+ if (linkedAccountTO.getPlainAttr(schema.getKey()).isPresent()) {
+ fixedAttrs.add(linkedAccountTO.getPlainAttr(schema.getKey()).get());
+ } else if (userTO.getPlainAttr(schema.getKey()).isPresent()) {
+ fixedAttrs.add(userTO.getPlainAttr(schema.getKey()).get());
+ }
+ });
+ }
+
+ private class PlainSchemasOwn extends PlainSchemas<List<AttrTO>> {
+
+ private static final long serialVersionUID = -4730563859116024676L;
+
+ PlainSchemasOwn(
+ final String id,
+ final Map<String, PlainSchemaTO> schemas,
+ final IModel<List<AttrTO>> attrTOs) {
+
+ super(id, schemas, attrTOs);
+
+ add(new ListView<AttrTO>("schemas", attrTOs) {
+
+ private static final long serialVersionUID = 9101744072914090143L;
+
+ @Override
+ protected void populateItem(final ListItem<AttrTO> item) {
+ AttrTO attrTO = item.getModelObject();
+ final boolean isMultivalue = schemas.get(attrTO.getSchema()).isMultivalue();
+
+ AbstractFieldPanel<?> panel = setPanel(
+ schemas,
+ item,
+ !linkedAccountTO.getPlainAttr(attrTO.getSchema()).isPresent());
+
+ panel.showExternAction(checkboxToggle(attrTO, panel, isMultivalue));
+ }
+ });
+ }
+ }
+
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.java
new file mode 100644
index 0000000..bc2864c
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.java
@@ -0,0 +1,66 @@
+/*
+ * 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.wizards.any;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.syncope.client.console.rest.ApplicationRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.util.ListModel;
+
+public class LinkedAccountPrivilegesPanel extends WizardStep {
+
+ private static final long serialVersionUID = 3388483585148725922L;
+
+ private final ApplicationRestClient applicationRestClient = new ApplicationRestClient();
+
+ public LinkedAccountPrivilegesPanel(final LinkedAccountTO linkedAccountTO) {
+ super();
+ setOutputMarkupId(true);
+
+ final LoadableDetachableModel<List<String>> availablePrivilges = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ return applicationRestClient.list().stream().
+ flatMap(app -> app.getPrivileges().stream()).
+ map(privilege -> privilege.getKey()).
+ distinct().
+ sorted().
+ collect(Collectors.toList());
+ }
+ };
+ AjaxPalettePanel<String> privilegesPanel = new AjaxPalettePanel.Builder<String>().
+ setAllowOrder(true).
+ setAllowMoveAll(true).
+ build("privileges",
+ new PropertyModel<>(linkedAccountTO, "privileges"),
+ new ListModel<>(availablePrivilges.getObject()));
+ privilegesPanel.hideLabel();
+ privilegesPanel.setOutputMarkupId(true);
+ add(privilegesPanel);
+ }
+
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
new file mode 100644
index 0000000..065aa3e
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
@@ -0,0 +1,130 @@
+/*
+ * 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.wizards.any;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.syncope.client.console.rest.UserRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal.ModalEvent;
+import org.apache.syncope.client.console.wizards.AjaxWizard;
+import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
+import org.apache.syncope.common.lib.patch.LinkedAccountPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+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;
+
+/**
+ * Accounts wizard builder.
+ */
+public class LinkedAccountWizardBuilder extends AjaxWizardBuilder<LinkedAccountTO> {
+
+ private static final long serialVersionUID = -9142332740863374891L;
+
+ private final UserRestClient userRestClient = new UserRestClient();
+
+ private UserTO userTO;
+
+ private final String userKey;
+
+ public LinkedAccountWizardBuilder(final String userKey, final PageReference pageRef) {
+ super(new LinkedAccountTO(), pageRef);
+ this.userKey = userKey;
+ this.userTO = userRestClient.read(userKey);
+ }
+
+ @Override
+ public AjaxWizard<LinkedAccountTO> build(final String id, final AjaxWizard.Mode mode) {
+ this.userTO = userRestClient.read(userKey);
+ return super.build(id, mode);
+ }
+
+ @Override
+ 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 LinkedAccountPrivilegesPanel(modelObject));
+ return wizardModel;
+ }
+
+ @Override
+ protected Serializable onApplyInternal(final LinkedAccountTO modelObject) {
+ fixPlainAttrs(modelObject);
+
+ LinkedAccountPatch linkedAccountPatch = new LinkedAccountPatch.Builder().linkedAccountTO(modelObject).build();
+ linkedAccountPatch.setLinkedAccountTO(modelObject);
+ UserPatch patch = new UserPatch();
+ patch.setKey(userTO.getKey());
+ patch.getLinkedAccounts().add(linkedAccountPatch);
+ userRestClient.update(userTO.getETagValue(), patch);
+
+ return modelObject;
+ }
+
+ private void fixPlainAttrs(final LinkedAccountTO linkedAccountTO) {
+ Set<AttrTO> validAttrs = new HashSet<>(linkedAccountTO.getPlainAttrs().stream().
+ filter(attr -> !attr.getValues().isEmpty()).
+ collect(Collectors.toSet()));
+ linkedAccountTO.getPlainAttrs().clear();
+ linkedAccountTO.getPlainAttrs().addAll(validAttrs);
+ }
+
+ @Override
+ protected Serializable getCreateCustomPayloadEvent(final Serializable afterObject, final AjaxRequestTarget target) {
+ LinkedAccountTO linkedAccountTO = LinkedAccountTO.class.cast(afterObject);
+ return new CreateEvent(
+ linkedAccountTO.getConnObjectKeyValue(),
+ userTO,
+ target);
+ }
+
+ private static class CreateEvent extends ModalEvent {
+
+ private static final long serialVersionUID = 6416834092156281986L;
+
+ private final String key;
+
+ private final UserTO userTO;
+
+ CreateEvent(
+ final String key,
+ final UserTO userTO,
+ final AjaxRequestTarget target) {
+
+ super(target);
+ this.key = key;
+ this.userTO = userTO;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public UserTO getUserTO() {
+ return userTO;
+ }
+ }
+
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
index edeaa95..32467a2 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
@@ -23,28 +23,14 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.stream.Collectors;
-import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.SchemaUtils;
-import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.tabs.Accordion;
import org.apache.syncope.client.console.wicket.markup.html.form.AbstractFieldPanel;
-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.AjaxSpinnerFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.BinaryFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDateFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDateTimeFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.EncryptedFieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
import org.apache.syncope.client.console.wizards.AjaxWizard;
import org.apache.syncope.common.lib.EntityTOUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.AttrTO;
@@ -54,20 +40,16 @@ import org.apache.syncope.common.lib.to.GroupableRelatableTO;
import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.PlainSchemaTO;
import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.wicket.PageReference;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.extensions.markup.html.tabs.ITab;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.model.util.ListModel;
@@ -76,12 +58,6 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
private static final long serialVersionUID = 552437609667518888L;
- protected final AjaxWizard.Mode mode;
-
- protected final AnyTO previousObject;
-
- protected String fileKey = "";
-
public <T extends AnyTO> PlainAttrs(
final AnyWrapper<T> modelObject,
final Form<?> form,
@@ -90,7 +66,6 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
final List<String> whichPlainAttrs) throws IllegalArgumentException {
super(modelObject, anyTypeClasses, whichPlainAttrs);
- this.mode = mode;
if (modelObject.getInnerObject() instanceof UserTO) {
fileKey = UserTO.class.cast(modelObject.getInnerObject()).getUsername();
@@ -224,168 +199,27 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
membershipTO.getPlainAttrs().addAll(attrs);
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
- protected FieldPanel getFieldPanel(final PlainSchemaTO schemaTO) {
- final boolean required;
- final boolean readOnly;
- final AttrSchemaType type;
- final boolean jexlHelp;
-
- if (mode == AjaxWizard.Mode.TEMPLATE) {
- required = false;
- readOnly = false;
- type = AttrSchemaType.String;
- jexlHelp = true;
- } else {
- required = schemaTO.getMandatoryCondition().equalsIgnoreCase("true");
- readOnly = schemaTO.isReadonly();
- type = schemaTO.getType();
- jexlHelp = false;
-
- }
-
- FieldPanel panel;
- switch (type) {
- case Boolean:
- panel = new AjaxCheckBoxPanel(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- new Model<>(),
- true);
- panel.setRequired(required);
- break;
-
- case Date:
- String datePattern = schemaTO.getConversionPattern() == null
- ? SyncopeConstants.DEFAULT_DATE_PATTERN
- : schemaTO.getConversionPattern();
-
- if (datePattern.contains("H")) {
- panel = new AjaxDateTimeFieldPanel(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- new Model<>(),
- datePattern);
- } else {
- panel = new AjaxDateFieldPanel(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- new Model<>(),
- datePattern);
- }
-
- if (required) {
- panel.addRequiredLabel();
- }
-
- break;
-
- case Enum:
- panel = new AjaxDropDownChoicePanel<>("panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
- ((AjaxDropDownChoicePanel<String>) panel).setChoices(SchemaUtils.getEnumeratedValues(schemaTO));
-
- if (StringUtils.isNotBlank(schemaTO.getEnumerationKeys())) {
- ((AjaxDropDownChoicePanel) panel).setChoiceRenderer(new IChoiceRenderer<String>() {
-
- private static final long serialVersionUID = -3724971416312135885L;
-
- private final Map<String, String> valueMap = SchemaUtils.getEnumeratedKeyValues(schemaTO);
-
- @Override
- public String getDisplayValue(final String value) {
- return valueMap.get(value) == null ? value : valueMap.get(value);
- }
-
- @Override
- public String getIdValue(final String value, final int i) {
- return value;
- }
-
- @Override
- public String getObject(
- final String id, final IModel<? extends List<? extends String>> choices) {
- return id;
- }
- });
- }
-
- if (required) {
- panel.addRequiredLabel();
- }
- break;
-
- case Long:
- panel = new AjaxSpinnerFieldPanel.Builder<Long>().enableOnChange().build(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- Long.class,
- new Model<>());
-
- if (required) {
- panel.addRequiredLabel();
- }
- break;
-
- case Double:
- panel = new AjaxSpinnerFieldPanel.Builder<Double>().enableOnChange().step(0.1).build(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- Double.class,
- new Model<>());
-
- if (required) {
- panel.addRequiredLabel();
- }
- break;
-
- case Binary:
- final PageReference pageRef = getPageReference();
- panel = new BinaryFieldPanel(
- "panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()),
- new Model<>(),
- schemaTO.getMimeType(),
- fileKey) {
-
- private static final long serialVersionUID = -3268213909514986831L;
-
- @Override
- protected PageReference getPageReference() {
- return pageRef;
- }
+ protected class PlainSchemasOwn extends PlainSchemas<List<AttrTO>> {
- };
- if (required) {
- panel.addRequiredLabel();
- }
- break;
+ private static final long serialVersionUID = -4730563859116024676L;
- case Encrypted:
- panel = new EncryptedFieldPanel("panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+ public PlainSchemasOwn(
+ final String id,
+ final Map<String, PlainSchemaTO> schemas,
+ final IModel<List<AttrTO>> attrTOs) {
- if (required) {
- panel.addRequiredLabel();
- }
- break;
+ super(id, schemas, attrTOs);
- default:
- panel = new AjaxTextFieldPanel("panel",
- schemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true);
+ add(new ListView<AttrTO>("schemas", attrTOs) {
- if (jexlHelp) {
- AjaxTextFieldPanel.class.cast(panel).enableJexlHelp();
- }
+ private static final long serialVersionUID = 9101744072914090143L;
- if (required) {
- panel.addRequiredLabel();
+ @Override
+ protected void populateItem(final ListItem<AttrTO> item) {
+ setPanel(schemas, item, false);
}
+ });
}
-
- panel.setReadOnly(readOnly);
-
- return panel;
}
protected class PlainSchemasMemberships extends PlainSchemas<AttributableTO> {
@@ -439,79 +273,4 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
}
}
- protected class PlainSchemasOwn extends PlainSchemas<List<AttrTO>> {
-
- private static final long serialVersionUID = -4730563859116024676L;
-
- public PlainSchemasOwn(
- final String id,
- final Map<String, PlainSchemaTO> schemas,
- final IModel<List<AttrTO>> attrTOs) {
-
- super(id, schemas, attrTOs);
-
- add(new ListView<AttrTO>("schemas", attrTOs) {
-
- private static final long serialVersionUID = 9101744072914090143L;
-
- @Override
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected void populateItem(final ListItem<AttrTO> item) {
- AttrTO attrTO = item.getModelObject();
-
- AbstractFieldPanel<?> panel = getFieldPanel(schemas.get(attrTO.getSchema()));
- if (mode == AjaxWizard.Mode.TEMPLATE
- || !schemas.get(attrTO.getSchema()).isMultivalue()) {
-
- FieldPanel.class.cast(panel).setNewModel(attrTO.getValues());
- } else {
- // SYNCOPE-1476 set form as multipart to properly manage membership attributes
- panel = new MultiFieldPanel.Builder<>(
- new PropertyModel<>(attrTO, "values")).build(
- "panel",
- attrTO.getSchema(),
- FieldPanel.class.cast(panel)).setFormAsMultipart(true);
- // SYNCOPE-1215 the entire multifield panel must be readonly, not only its field
- ((MultiFieldPanel) panel).setReadOnly(schemas.get(attrTO.getSchema()).isReadonly());
- }
- item.add(panel);
-
- setExternalAction(attrTO, panel);
- }
- });
- }
- }
-
- protected abstract class PlainSchemas<T> extends Schemas {
-
- private static final long serialVersionUID = 8315035592714180404L;
-
- public PlainSchemas(
- final String id,
- final Map<String, PlainSchemaTO> schemas,
- final IModel<T> attrTOs) {
-
- super(id);
- }
-
- protected void setExternalAction(final AttrTO attrTO, final AbstractFieldPanel<?> panel) {
- Optional<AttrTO> prevAttr = previousObject == null
- ? Optional.empty()
- : previousObject.getPlainAttr(attrTO.getSchema());
- if (previousObject != null
- && ((!prevAttr.isPresent() && attrTO.getValues().stream().anyMatch(StringUtils::isNotBlank))
- || (prevAttr.isPresent() && !ListUtils.isEqualList(
- prevAttr.get().getValues().stream().
- filter(StringUtils::isNotBlank).collect(Collectors.toList()),
- attrTO.getValues().stream().
- filter(StringUtils::isNotBlank).collect(Collectors.toList()))))) {
-
- List<String> oldValues = prevAttr.isPresent()
- ? prevAttr.get().getValues()
- : Collections.<String>emptyList();
- panel.showExternAction(new LabelInfo("externalAction", oldValues));
- }
- }
- }
-
}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java
index 2e5f725..139feb5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/TypeExtensionWizardBuilder.java
@@ -112,7 +112,7 @@ public class TypeExtensionWizardBuilder extends AjaxWizardBuilder<TypeExtensionT
map(EntityTO::getKey).collect(Collectors.toList());
AjaxPalettePanel<String> auxClassesPalette = new AjaxPalettePanel.Builder<String>().build(
"auxClasses.palette",
- new PropertyModel<List<String>>(typeExtensionTO, "auxClasses"),
+ new PropertyModel<>(typeExtensionTO, "auxClasses"),
new ListModel<>(anyTypeClasses));
add(auxClassesPalette.hideLabel().setOutputMarkupId(true));
}
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
similarity index 89%
copy from client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
index d0d803f..dd5288c 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.html
@@ -18,9 +18,7 @@ under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
- <div id="emptyPlaceholder"/>
- <div id="attributes">
- <wicket:child/>
- </div>
+ <span wicket:id="linkedAccountsList">[linkedAccountsList]</span>
+ <div wicket:id="toggle"/>
</wicket:panel>
</html>
\ No newline at end of file
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.properties
index ebae232..5f28a07 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Resource
+suspended=Suspended
+connObjectKeyValue=External key
+inner.edit.linkedAccount=Edit account
+inner.create.linkedAccount=Create account
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_it.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_it.properties
index ebae232..ce0bcf8 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_it.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Risorsa
+suspended=Sospeso
+connObjectKeyValue=Chiave esterna
+inner.edit.linkedAccount=Modifica account
+inner.create.linkedAccount=Crea account
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ja.properties
similarity index 74%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ja.properties
index ebae232..b825afb 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ja.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=\u8cc7\u6e90
+suspended=\u4e00\u6642\u505c\u6b62
+connObjectKeyValue=\u5916\u90e8\u30ad\u30fc
+inner.edit.linkedAccount=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u7de8\u96c6
+inner.create.linkedAccount=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u4f5c\u6210\u3059\u308b
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_pt_BR.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_pt_BR.properties
index ebae232..62a2310 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_pt_BR.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Recurso
+suspended=Suspenso
+connObjectKeyValue=Chave externa
+inner.edit.linkedAccount=Editar conta
+inner.create.linkedAccount=Criar Conta
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ru.properties
similarity index 63%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ru.properties
index ebae232..8a337d3 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/LinkedAccountModalPanel_ru.properties
@@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=\u0420\u0435\u0441\u0443\u0440\u0441
+suspended=\u043f\u043e\u0434\u0432\u0435\u0448\u0435\u043d\u043d\u044b\u0439
+connObjectKeyValue=\u0412\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u043b\u044e\u0447
+inner.edit.linkedAccount=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u043a\u043a\u0430\u0443\u043d\u0442
+inner.create.linkedAccount=\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
index ebae232..6acf5db 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
@@ -17,3 +17,4 @@
any.edit=Edit ${anyTO.type} ${anyTO.username}
any.propagation.tasks=Propagation tasks for ${type} ${username}
any.notification.tasks=Notification tasks for ${type} ${username}
+linkedAccounts.title=Manage user accounts
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties
index 1b03294..38fa14d 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties
@@ -17,3 +17,4 @@
any.edit=Modifica ${anyTO.type} ${anyTO.username}
any.propagation.tasks=Task di propagazione per ${type} ${username}
any.notification.tasks=Task di notifica per ${type} ${username}
+linkedAccounts.title=Gestisci account utente
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties
index c8baff6..9107368 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties
@@ -17,3 +17,4 @@
any.edit=${anyTO.type} ${anyTO.username} \u3092\u7de8\u96c6
any.propagation.tasks=${type} ${username} \u306e\u4f1d\u64ad\u30bf\u30b9\u30af
any.notification.tasks=${type} ${username} \u306e\u901a\u77e5\u30bf\u30b9\u30af
+linkedAccounts.title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7ba1\u7406\u3059\u308b
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties
index 9498b19..865e74d 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties
@@ -17,3 +17,4 @@
any.edit=Alterar ${anyTO.type} ${anyTO.username}
any.propagation.tasks=Propagation tasks for ${type} ${username}
any.notification.tasks=Notification tasks for ${type} ${username}
+linkedAccounts.title=Gerenciar contas de usu\u00e1rio
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties
index ad11a87..53e0e86 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties
@@ -18,3 +18,4 @@
any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${anyTO.type} ${anyTO.username}
any.propagation.tasks=\u0417\u0430\u0434\u0430\u0447\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0434\u043b\u044f ${type} ${username}
any.notification.tasks=\u0417\u0430\u0434\u0430\u0447\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0434\u043b\u044f ${type} ${username}
+linkedAccounts.title=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u043c\u0438 \u0437\u0430\u043f\u0438\u0441\u044f\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties
index e5affd7..6831a2b 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties
@@ -233,3 +233,7 @@ zoom_in.alt=zoom-in icon
zoom_out.class=fa fa-search-minus
zoom_out.title=zoom-out
zoom_out.alt=zoom-out icon
+
+manage_accounts.class=fa fa-users
+manage_accounts.title=manage accounts
+manage_accounts.alt=manage accounts icon
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties
index d0dbb16..2e13f6e 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties
@@ -231,3 +231,7 @@ reconciliation_push.alt=reconciliation push icon
reconciliation_pull.class=fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
+
+manage_accounts.class=fa fa-users
+manage_accounts.title=gestisci account
+manage_accounts.alt=manage accounts icon
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties
index 130e63c..421abc9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties
@@ -231,3 +231,7 @@ reconciliation_push.alt=\u7167\u5408\u30d7\u30c3\u30b7\u30e5 icon
reconciliation_pull.class=fa-chevron-circle-left
reconciliation_pull.title=\u30d7\u30eb
reconciliation_pull.alt=\u7167\u5408\u30d7\u30eb icon
+
+manage_accounts.class=fa fa-users
+manage_accounts.title=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7ba1\u7406\u3059\u308b
+manage_accounts.alt=\u30a2\u30ab\u30a6\u30f3\u30c8\u7ba1\u7406\u30a2\u30a4\u30b3\u30f3
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties
index 4aedf76..7a61862 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties
@@ -231,3 +231,7 @@ reconciliation_push.alt=reconciliation push icon
reconciliation_pull.class=fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
+
+manage_accounts.class=fa fa-users
+manage_accounts.title=manage accounts
+manage_accounts.alt=manage accounts icon
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties
index e7fc2d3..d825127 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties
@@ -231,3 +231,7 @@ reconciliation_push.alt=reconciliation push icon
reconciliation_pull.class=fa-chevron-circle-left
reconciliation_pull.title=pull
reconciliation_pull.alt=reconciliation pull icon
+
+manage_accounts.class=fa fa-users
+manage_accounts.title=manage accounts
+manage_accounts.alt=manage accounts icon
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
index d0d803f..2c13529 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
@@ -17,10 +17,7 @@ specific language governing permissions and limitations
under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
- <wicket:panel>
- <div id="emptyPlaceholder"/>
- <div id="attributes">
- <wicket:child/>
- </div>
- </wicket:panel>
+ <wicket:extend>
+ <wicket:child/>
+ </wicket:extend>
</html>
\ No newline at end of file
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs$Schemas.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep$Schemas.html
similarity index 100%
rename from client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs$Schemas.html
rename to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep$Schemas.html
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.html
similarity index 100%
copy from client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.html
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.html
similarity index 68%
copy from client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.html
index e2da0f2..ed2f180 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.html
@@ -19,11 +19,19 @@ under the License.
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<div class="form-group">
- <span wicket:id="overrideCapabilities">[overrideCapabilities]</span>
- </div>
-
- <div class="form-group">
- <span wicket:id="capabilities">[capabilitiesOverride]</span>
+ <div class="box">
+ <div class="box-header with-border">
+ <h3 class="box-title"><wicket:message key="title"/></h3>
+ </div>
+ <div class="box-body">
+ <div id="group-forum">
+ <span wicket:id="username">[username]</span>
+ </div>
+ <div id="group-forum">
+ <span wicket:id="password">[password]</span>
+ </div>
+ </div>
+ </div>
</div>
</wicket:panel>
</html>
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.properties
index ebae232..387b986 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=Username
+password=Password
+title=Credentials
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_it.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_it.properties
index ebae232..c98ccb0 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_it.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=Username
+password=Password
+title=Credenziali
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ja.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ja.properties
index ebae232..6a73f2a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ja.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=\u30e6\u30fc\u30b6\u30fc\u540d
+password=\u30d1\u30b9\u30ef\u30fc\u30c9
+title=\u8cc7\u683c\u60c5\u5831
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_pt_BR.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_pt_BR.properties
index ebae232..cbef682 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_pt_BR.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=Username
+password=Password
+title=Credenciais
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ru.properties
similarity index 78%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ru.properties
index ebae232..219c104 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel_ru.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+username=\u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
+password=\u043f\u0430\u0440\u043e\u043b\u044c
+title=\u043f\u043e\u043b\u043d\u043e\u043c\u043e\u0447\u0438\u044f
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.html
similarity index 67%
copy from client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.html
index e2da0f2..f2087ab 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.html
@@ -19,11 +19,19 @@ under the License.
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<div class="form-group">
- <span wicket:id="overrideCapabilities">[overrideCapabilities]</span>
- </div>
-
- <div class="form-group">
- <span wicket:id="capabilities">[capabilitiesOverride]</span>
+ <div class="box">
+ <div class="box-header with-border">
+ <h3 class="box-title"><wicket:message key="title"/></h3>
+ </div>
+ <div class="box-body">
+ <div id="group-forum">
+ <span wicket:id="resource">[resource]</span>
+ </div>
+ <div id="group-forum">
+ <span wicket:id="connObjectKeyValue">[connObjectKeyValue]</span>
+ </div>
+ </div>
+ </div>
</div>
</wicket:panel>
</html>
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.properties
index ebae232..c820770 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Resource
+connObjectKeyValue=Value of the key of the object as on the external resource
+title=Details
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_it.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_it.properties
index ebae232..b098daf 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_it.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Risorsa
+connObjectKeyValue=Valore della chiave dell'oggetto come com'\u00e8 sulla risorsa esterna
+title=Dettagli
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ja.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ja.properties
index ebae232..03d0baa 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ja.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=\u8cc7\u6e90
+connObjectKeyValue=\u5916\u90e8\u30ea\u30bd\u30fc\u30b9\u4e0a\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u30ad\u30fc\u306e\u5024
+title=\u8a73\u7d30
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_pt_BR.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_pt_BR.properties
index ebae232..9d1da54 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_pt_BR.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=Recurso
+connObjectKeyValue=Valor da chave do objeto como no recurso externo
+title=Detalhes
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ru.properties
similarity index 67%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ru.properties
index ebae232..bbaba52 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel_ru.properties
@@ -14,6 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+resource=\u0420\u0435\u0441\u0443\u0440\u0441
+connObjectKeyValue=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043a\u0430\u043a \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u0435\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0435
+title=\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.html
similarity index 86%
copy from client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.html
index d0d803f..5310309 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AbstractAttrs.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.html
@@ -17,10 +17,7 @@ specific language governing permissions and limitations
under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
- <wicket:panel>
- <div id="emptyPlaceholder"/>
- <div id="attributes">
- <wicket:child/>
- </div>
- </wicket:panel>
+ <wicket:extend>
+ <div wicket:id="plainSchemas"/>
+ </wicket:extend>
</html>
\ No newline at end of file
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.properties
index ebae232..2456923 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_it.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_it.properties
index ebae232..2456923 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_it.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_ja.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_ja.properties
index ebae232..13a8339 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_ja.properties
@@ -14,6 +14,3 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_pt_BR.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_pt_BR.properties
index ebae232..13a8339 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_pt_BR.properties
@@ -14,6 +14,3 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_ru.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_ru.properties
index ebae232..13a8339 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel_ru.properties
@@ -14,6 +14,3 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.html
similarity index 74%
copy from client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.html
index e2da0f2..7a9b812 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.html
@@ -19,11 +19,16 @@ under the License.
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<div class="form-group">
- <span wicket:id="overrideCapabilities">[overrideCapabilities]</span>
- </div>
-
- <div class="form-group">
- <span wicket:id="capabilities">[capabilitiesOverride]</span>
+ <div class="box">
+ <div class="box-header with-border">
+ <h3 class="box-title"><wicket:message key="title"/></h3>
+ </div>
+ <div class="box-body">
+ <div id="group-forum">
+ <span wicket:id="privileges">[privileges]</span>
+ </div>
+ </div>
+ </div>
</div>
</wicket:panel>
</html>
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.properties
index ebae232..5887b81 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=Privileges
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_it.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_it.properties
index ebae232..8b9d8d5 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_it.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=Privilegi
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ja.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ja.properties
index ebae232..c83d230 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ja.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=\u7279\u5178
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_pt_BR.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_pt_BR.properties
index ebae232..2ef9db4 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_pt_BR.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=Privil\u00e9gios
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ru.properties
similarity index 81%
copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
copy to client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ru.properties
index ebae232..4d83a4c 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/LinkedAccountPrivilegesPanel_ru.properties
@@ -14,6 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-any.edit=Edit ${anyTO.type} ${anyTO.username}
-any.propagation.tasks=Propagation tasks for ${type} ${username}
-any.notification.tasks=Notification tasks for ${type} ${username}
+title=\u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0438
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
index e2da0f2..97c6734 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceConnCapabilitiesPanel.html
@@ -23,7 +23,7 @@ under the License.
</div>
<div class="form-group">
- <span wicket:id="capabilities">[capabilitiesOverride]</span>
+ <span wicket:id="capabilities">[capabilities]</span>
</div>
</wicket:panel>
</html>
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/LinkedAccountTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/LinkedAccountTO.java
index f2f0387..d091c10 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/LinkedAccountTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/LinkedAccountTO.java
@@ -29,10 +29,11 @@ import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.syncope.common.lib.BaseBean;
@XmlRootElement(name = "linkedAccount")
@XmlType
-public class LinkedAccountTO implements EntityTO {
+public class LinkedAccountTO extends BaseBean implements EntityTO {
private static final long serialVersionUID = 7396929732310559535L;
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/LinkedAccountPlainAttrProperty.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/LinkedAccountPlainAttrProperty.java
new file mode 100644
index 0000000..2d6f1df
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/LinkedAccountPlainAttrProperty.java
@@ -0,0 +1,100 @@
+/*
+ * 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.common.lib.types;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+@XmlRootElement
+@XmlType
+public class LinkedAccountPlainAttrProperty implements Serializable, Comparable<LinkedAccountPlainAttrProperty> {
+
+ private static final long serialVersionUID = -5309050337675968950L;
+
+ private String schema;
+
+ private final List<String> values = new ArrayList<>();
+
+ private boolean overridable;
+
+ public String getSchema() {
+ return schema;
+ }
+
+ public void setSchema(final String schema) {
+ this.schema = schema;
+ }
+
+ @XmlElementWrapper(name = "values")
+ @XmlElement(name = "value")
+ @JsonProperty("values")
+ public List<String> getValues() {
+ return values;
+ }
+
+ public boolean isOverridable() {
+ return overridable;
+ }
+
+ public void setOverridable(final boolean overridable) {
+ this.overridable = overridable;
+ }
+
+ @Override
+ public int compareTo(final LinkedAccountPlainAttrProperty connConfProperty) {
+ return ObjectUtils.compare(this.getSchema(), connConfProperty.getSchema());
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().
+ append(schema).
+ append(values).
+ append(overridable).
+ build();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final LinkedAccountPlainAttrProperty other = (LinkedAccountPlainAttrProperty) obj;
+ return new EqualsBuilder().
+ append(schema, other.schema).
+ append(values, other.values).
+ append(overridable, other.overridable).
+ build();
+ }
+}
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java
index ca6f63d..0837b9e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java
@@ -784,7 +784,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
TESTER.executeAjaxEvent(TESTER.getComponentFromLastRenderedPage(
"body:content:body:container:content:tabbedPanel:panel:searchResult:outerObjectsRepeater:"
- + "1:outer:container:content:togglePanelContainer:container:actions:actions:actionRepeater:8:"
+ + "1:outer:container:content:togglePanelContainer:container:actions:actions:actionRepeater:9:"
+ "action:action"), Constants.ON_CLICK);
TESTER.assertInfoMessages("Operation executed successfully");
@@ -792,7 +792,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
component = findComponentByProp("username",
"body:content:body:container:content:tabbedPanel:panel:searchResult:container:content:"
- + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini_clone");
+ + "searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini_clone");
assertNull(component);
// delete default policy
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
index 691ec4e..fc3258b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
@@ -547,7 +547,7 @@ public class UsersITCase extends AbstractConsoleITCase {
TESTER.executeAjaxEvent(component.getPageRelativePath(), Constants.ON_CLICK);
TESTER.assertComponent(TAB_PANEL
+ "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
- + "actions:actions:actionRepeater:8:action:action", IndicatingOnConfirmAjaxLink.class);
+ + "actions:actions:actionRepeater:9:action:action", IndicatingOnConfirmAjaxLink.class);
}
@Test