You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2017/06/29 15:26:23 UTC
syncope git commit: [SYNCOPE-1135] provides dynamicac reload of
groups and memberships if the realm changes
Repository: syncope
Updated Branches:
refs/heads/2_0_X 132d4156d -> a25b7c6fb
[SYNCOPE-1135] provides dynamicac reload of groups and memberships if the realm changes
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/a25b7c6f
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/a25b7c6f
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/a25b7c6f
Branch: refs/heads/2_0_X
Commit: a25b7c6fb40d1444f50feb3bebad33d0d6f7c966
Parents: 132d415
Author: fmartelli <fa...@gmail.com>
Authored: Thu Jun 29 17:26:04 2017 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Thu Jun 29 17:26:04 2017 +0200
----------------------------------------------------------------------
.../syncope/client/console/pages/Realms.java | 4 +
.../client/console/panels/RealmChoicePanel.java | 26 +-
.../client/console/wizards/any/Details.java | 15 +-
.../client/console/wizards/any/Groups.java | 236 +++++++++++++------
4 files changed, 197 insertions(+), 84 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/a25b7c6f/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index d1c204c..0a8e9ad 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -254,4 +254,8 @@ public class Realms extends BasePage {
});
return content;
}
+
+ public RealmChoicePanel getRealmChoicePanel() {
+ return realmChoicePanel;
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a25b7c6f/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
index 4f0bbde..4a0ee0a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
@@ -76,6 +76,8 @@ public class RealmChoicePanel extends Panel {
private final Map<String, Pair<RealmTO, List<RealmTO>>> tree;
+ private final List<AbstractLink> links = new ArrayList<>();
+
public RealmChoicePanel(final String id, final PageReference pageRef) {
super(id);
this.pageRef = pageRef;
@@ -172,11 +174,11 @@ public class RealmChoicePanel extends Panel {
@Override
protected List<AbstractLink> newSubMenuButtons(final String buttonMarkupId) {
- List<AbstractLink> links = new ArrayList<>();
+ RealmChoicePanel.this.links.clear();
- links.add(new BootstrapAjaxLink<String>(
+ RealmChoicePanel.this.links.add(new BootstrapAjaxLink<RealmTO>(
ButtonList.getButtonMarkupId(),
- new Model<String>(),
+ new Model<RealmTO>(),
Buttons.Type.Link,
new ResourceModel("realms", "Realms")) {
@@ -201,9 +203,9 @@ public class RealmChoicePanel extends Panel {
for (Pair<String, RealmTO> link : realmTree.getObject()) {
final RealmTO realmTO = link.getValue();
- links.add(new BootstrapAjaxLink<String>(
+ RealmChoicePanel.this.links.add(new BootstrapAjaxLink<RealmTO>(
ButtonList.getButtonMarkupId(),
- new Model<String>(),
+ Model.of(realmTO),
Buttons.Type.Link,
new Model<>(link.getKey())) {
@@ -232,9 +234,9 @@ public class RealmChoicePanel extends Panel {
}
if (!dynRealmTree.getObject().isEmpty()) {
- links.add(new BootstrapAjaxLink<String>(
+ RealmChoicePanel.this.links.add(new BootstrapAjaxLink<RealmTO>(
ButtonList.getButtonMarkupId(),
- new Model<String>(),
+ new Model<RealmTO>(),
Buttons.Type.Link,
new ResourceModel("dynrealms", "Dynamic Realms")) {
@@ -263,9 +265,9 @@ public class RealmChoicePanel extends Panel {
realmTO.setName(dynRealmTO.getKey());
realmTO.setFullPath(dynRealmTO.getKey());
- links.add(new BootstrapAjaxLink<String>(
+ RealmChoicePanel.this.links.add(new BootstrapAjaxLink<RealmTO>(
ButtonList.getButtonMarkupId(),
- new Model<String>(),
+ new Model<RealmTO>(),
Buttons.Type.Link,
new Model<>(realmTO.getKey())) {
@@ -295,7 +297,7 @@ public class RealmChoicePanel extends Panel {
}
}
- return links;
+ return RealmChoicePanel.this.links;
}
};
realms.setOutputMarkupId(true);
@@ -404,4 +406,8 @@ public class RealmChoicePanel extends Panel {
return target;
}
}
+
+ public List<AbstractLink> getLinks() {
+ return links;
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a25b7c6f/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
index 61e4884..e5a92d2 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
@@ -19,9 +19,10 @@
package org.apache.syncope.client.console.wizards.any;
import java.util.ArrayList;
+import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.client.console.rest.RealmRestClient;
+import org.apache.syncope.client.console.pages.Realms;
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.console.wicket.markup.html.form.FieldPanel;
@@ -29,6 +30,7 @@ import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.wicket.PageReference;
import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.markup.html.link.AbstractLink;
import org.apache.wicket.model.PropertyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,11 +60,20 @@ public class Details<T extends AnyTO> extends WizardStep {
"destinationRealm", "destinationRealm", new PropertyModel<String>(inner, "realm"), false);
AjaxTextFieldPanel.class.cast(realm).enableJexlHelp();
} else {
+ final List<AbstractLink> realmLinks = Realms.class.cast(pageRef.getPage()).getRealmChoicePanel().getLinks();
+ final List<RealmTO> realms = new ArrayList<>();
+ for (AbstractLink link : realmLinks) {
+ Object obj = link.getDefaultModelObject();
+ if (obj instanceof RealmTO) {
+ realms.add((RealmTO) obj);
+ }
+ }
+
realm = new AjaxDropDownChoicePanel<>(
"destinationRealm", "destinationRealm", new PropertyModel<String>(inner, "realm"), false);
((AjaxDropDownChoicePanel<String>) realm).setChoices(CollectionUtils.collect(
- new RealmRestClient().list(),
+ realms,
new Transformer<RealmTO, String>() {
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/a25b7c6f/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
index 0ea89e5..8e640fd 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
@@ -19,7 +19,9 @@
package org.apache.syncope.client.console.wizards.any;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.ListUtils;
@@ -62,15 +64,19 @@ public class Groups extends WizardStep implements ICondition {
private final List<DynRealmTO> allDynRealms = new DynRealmRestClient().list();
- private List<GroupTO> allGroups;
+ private GroupsModel groupsModel;
private final AnyTO anyTO;
+ private boolean templateMode;
+
public <T extends AnyTO> Groups(final AnyWrapper<T> modelObject, final boolean templateMode) {
super();
+ this.templateMode = templateMode;
this.anyTO = modelObject.getInnerObject();
- final String realm = templateMode ? "/" : this.anyTO.getRealm();
+
+ groupsModel = new GroupsModel();
// -----------------------------------------------------------------
// Pre-Authorizations
@@ -127,47 +133,17 @@ public class Groups extends WizardStep implements ICondition {
}
});
- allGroups = groupRestClient.search(
- realm,
- SyncopeClient.getGroupSearchConditionBuilder().isAssignable().query(),
- 1,
- MAX_GROUP_LIST_CARDINALITY,
- new SortParam<>("name", true),
- null);
-
- // ---------------------------------
- // Retrieve group memberships
- // ---------------------------------
- // this is to be sure to have group names (required to see membership details in approval page)
- GroupFiqlSearchConditionBuilder searchConditionBuilder = SyncopeClient.getGroupSearchConditionBuilder();
-
- List<CompleteCondition> conditions = new ArrayList<>();
- for (MembershipTO membershipTO : GroupableRelatableTO.class.cast(anyTO).getMemberships()) {
- conditions.add(searchConditionBuilder.is("key").equalTo(membershipTO.getGroupKey()).wrap());
- }
+ groupsContainer.add(builder.setAllowOrder(true).withFilter().build("groups",
+ new ListModel<MembershipTO>() {
- List<GroupTO> groups = new ArrayList<>();
- if (!conditions.isEmpty()) {
- groups.addAll(groupRestClient.search(
- "/",
- searchConditionBuilder.or(conditions).query(),
- -1,
- -1,
- new SortParam<>("name", true),
- null));
- }
+ private static final long serialVersionUID = -2583290457773357445L;
- // set group names in membership TOs
- for (GroupTO group : groups) {
- MembershipTO membership = GroupableRelatableTO.class.cast(anyTO).getMembership(group.getKey());
- if (membership != null) {
- membership.setGroupName(group.getName());
+ @Override
+ public List<MembershipTO> getObject() {
+ return Groups.this.groupsModel.getMemberships();
}
- }
- groupsContainer.add(builder.setAllowOrder(true).withFilter().build("groups",
- new ListModel<>(GroupableRelatableTO.class.cast(anyTO).getMemberships()),
- new AjaxPalettePanel.Builder.Query<MembershipTO>() {
+ }, new AjaxPalettePanel.Builder.Query<MembershipTO>() {
private static final long serialVersionUID = -7223078772249308813L;
@@ -175,11 +151,11 @@ public class Groups extends WizardStep implements ICondition {
public List<MembershipTO> execute(final String filter) {
return CollectionUtils.collect(
StringUtils.isEmpty(filter) || "*".equals(filter)
- ? allGroups
+ ? groupsModel.getObject()
: groupRestClient.search(
- realm,
+ anyTO.getRealm(),
SyncopeClient.getGroupSearchConditionBuilder().
- isAssignable().and().is("name").equalTo(filter).query(),
+ isAssignable().and().is("name").equalTo(filter).query(),
1, MAX_GROUP_LIST_CARDINALITY,
new SortParam<>("name", true),
null),
@@ -194,38 +170,19 @@ public class Groups extends WizardStep implements ICondition {
}, new ArrayList<MembershipTO>());
}
}).hideLabel().setOutputMarkupId(true));
- // ---------------------------------
- // ---------------------------------
- // Retrieve dyn group memberships
- // ---------------------------------
- searchConditionBuilder = SyncopeClient.getGroupSearchConditionBuilder();
+ dyngroupsContainer.add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).build("dyngroups",
+ new ListModel<String>() {
- conditions = new ArrayList<>();
- for (String groupKey : GroupableRelatableTO.class.cast(anyTO).getDynGroups()) {
- conditions.add(searchConditionBuilder.is("key").equalTo(groupKey).wrap());
- }
+ private static final long serialVersionUID = -2583290457773357445L;
- groups = new ArrayList<>();
- if (!conditions.isEmpty()) {
- groups.addAll(groupRestClient.search(
- "/",
- searchConditionBuilder.or(conditions).query(),
- -1,
- -1,
- new SortParam<>("name", true),
- null));
- }
-
- dyngroupsContainer.add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).build("dyngroups",
- new ListModel<>(CollectionUtils.collect(groups, new Transformer<GroupTO, String>() {
+ @Override
+ public List<String> getObject() {
+ return Groups.this.groupsModel.getDynMemberships();
+ }
- @Override
- public String transform(final GroupTO input) {
- return input.getName();
- }
- }, new ArrayList<String>())),
- new ListModel<>(CollectionUtils.collect(allGroups, new Transformer<GroupTO, String>() {
+ }, new ListModel<>(CollectionUtils.collect(groupsModel.getObject(),
+ new Transformer<GroupTO, String>() {
@Override
public String transform(final GroupTO input) {
@@ -264,8 +221,143 @@ public class Groups extends WizardStep implements ICondition {
public boolean evaluate() {
return ((anyTO instanceof GroupTO)
? CollectionUtils.isNotEmpty(allDynRealms)
- : CollectionUtils.isNotEmpty(allDynRealms) || CollectionUtils.isNotEmpty(allGroups))
+ : CollectionUtils.isNotEmpty(allDynRealms) || CollectionUtils.isNotEmpty(groupsModel.getObject()))
&& SyncopeConsoleApplication.get().getSecuritySettings().getAuthorizationStrategy().
- isActionAuthorized(this, RENDER);
+ isActionAuthorized(this, RENDER);
+ }
+
+ private class GroupsModel extends ListModel<GroupTO> {
+
+ private static final long serialVersionUID = -4541954630939063927L;
+
+ private List<GroupTO> groups;
+
+ private List<MembershipTO> memberships;
+
+ private List<String> dynMemberships;
+
+ private String realm;
+
+ @Override
+ public List<GroupTO> getObject() {
+ reload();
+ return groups;
+ }
+
+ /**
+ * Retrieve the first MAX_GROUP_LIST_CARDINALITY assignable.
+ */
+ private void reloadObject() {
+ groups = groupRestClient.search(
+ realm,
+ SyncopeClient.getGroupSearchConditionBuilder().isAssignable().query(),
+ 1,
+ MAX_GROUP_LIST_CARDINALITY,
+ new SortParam<>("name", true),
+ null);
+ }
+
+ public List<MembershipTO> getMemberships() {
+ reload();
+ return memberships;
+ }
+
+ /**
+ * Retrieve group memberships.
+ */
+ private void reloadMemberships() {
+ // this is to be sure to have group names (required to see membership details in approval page)
+ GroupFiqlSearchConditionBuilder searchConditionBuilder = SyncopeClient.getGroupSearchConditionBuilder();
+
+ List<CompleteCondition> conditions = new ArrayList<>();
+ for (MembershipTO membershipTO : GroupableRelatableTO.class.cast(anyTO).getMemberships()) {
+ conditions.add(searchConditionBuilder.is("key").equalTo(membershipTO.getGroupKey()).wrap());
+ }
+
+ Map<String, GroupTO> assignedGroups = new HashMap<>();
+ if (!conditions.isEmpty()) {
+ for (GroupTO group : groupRestClient.search(
+ realm,
+ searchConditionBuilder.isAssignable().and().or(conditions).query(),
+ -1,
+ -1,
+ new SortParam<>("name", true),
+ null)) {
+ assignedGroups.put(group.getKey(), group);
+ }
+ }
+
+ // set group names in membership TOs and remove membership not assignable
+ List<MembershipTO> toBeRemoved = new ArrayList<>();
+ for (MembershipTO membership : GroupableRelatableTO.class.cast(anyTO).getMemberships()) {
+ if (assignedGroups.containsKey(membership.getRightKey())) {
+ membership.setGroupName(assignedGroups.get(membership.getRightKey()).getName());
+ } else {
+ toBeRemoved.add(membership);
+ }
+ }
+ GroupableRelatableTO.class.cast(anyTO).getMemberships().removeAll(toBeRemoved);
+
+ memberships = GroupableRelatableTO.class.cast(anyTO).getMemberships();
+ }
+
+ public List<String> getDynMemberships() {
+ reload();
+ return dynMemberships;
+ }
+
+ /**
+ * Retrieve dyn group memberships.
+ */
+ private void reloadDynMemberships() {
+ GroupFiqlSearchConditionBuilder searchConditionBuilder = SyncopeClient.getGroupSearchConditionBuilder();
+
+ ArrayList<CompleteCondition> conditions = new ArrayList<>();
+ for (String groupKey : GroupableRelatableTO.class.cast(anyTO).getDynGroups()) {
+ conditions.add(searchConditionBuilder.is("key").equalTo(groupKey).wrap());
+ }
+
+ Map<String, GroupTO> assignedGroups = new HashMap<>();
+ if (!conditions.isEmpty()) {
+ for (GroupTO group : groupRestClient.search(
+ "/",
+ searchConditionBuilder.or(conditions).query(),
+ -1,
+ -1,
+ new SortParam<>("name", true),
+ null)) {
+ assignedGroups.put(group.getKey(), group);
+ }
+ }
+
+ dynMemberships = CollectionUtils.collect(assignedGroups.values(), new Transformer<GroupTO, String>() {
+
+ @Override
+ public String transform(final GroupTO input) {
+ return input.getName();
+ }
+ }, new ArrayList<String>());
+ }
+
+ /**
+ * Reload data if the realm changes (see SYNCOPE-1135).
+ */
+ private void reload() {
+ boolean reload;
+
+ if (Groups.this.templateMode) {
+ reload = realm == null;
+ realm = "/";
+ } else {
+ reload = !Groups.this.anyTO.getRealm().equalsIgnoreCase(realm);
+ realm = Groups.this.anyTO.getRealm();
+ }
+
+ if (reload) {
+ reloadObject();
+ reloadMemberships();
+ reloadDynMemberships();
+ }
+ }
}
}