Repository: syncope Updated Branches: refs/heads/master 9a10f6e99 -> 04183d50f
[SYNCOPE-778] providing feature to force change password (bulk as well) Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/04183d50 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/04183d50 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/04183d50 Branch: refs/heads/master Commit: 04183d50fe8bd2e8f9e94a2e115a91c7bd4afac3 Parents: 9a10f6e Author: fmartelli <[email protected]> Authored: Wed Mar 16 17:47:23 2016 +0100 Committer: fmartelli <[email protected]> Committed: Wed Mar 16 17:47:23 2016 +0100 ---------------------------------------------------------------------- .../client/console/bulk/BulkContent.java | 13 +-- .../panels/AbstractSearchResultPanel.java | 8 +- .../console/panels/AjaxDataTablePanel.java | 7 +- .../panels/UserDisplayAttributesModalPanel.java | 2 +- .../console/panels/UserSearchResultPanel.java | 97 +++++++++++++------- .../client/console/rest/UserRestClient.java | 8 ++ .../wicket/markup/html/form/ActionLink.java | 1 + .../markup/html/form/ActionLinksPanel.java | 24 +++++ .../markup/html/form/ActionLinksPanel.html | 5 + .../syncope/common/lib/to/BulkAction.java | 1 + .../rest/cxf/service/AbstractAnyService.java | 58 +++++++++--- .../syncope/fit/console/BulkActionITCase.java | 6 +- 12 files changed, 165 insertions(+), 65 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java index 153c39c..caf5dce 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java @@ -29,7 +29,6 @@ import java.util.Map; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.commons.Constants; import org.apache.syncope.client.console.commons.status.StatusBean; -import org.apache.syncope.client.console.panels.AbstractSearchResultPanel.EventDataWrapper; import org.apache.syncope.client.console.panels.MultilevelPanel; import org.apache.syncope.client.console.rest.AbstractAnyRestClient; import org.apache.syncope.client.console.rest.BaseRestClient; @@ -44,7 +43,6 @@ import org.apache.syncope.common.lib.types.ResourceAssociationAction; import org.apache.syncope.common.lib.types.ResourceDeassociationAction; import org.apache.syncope.common.lib.types.StandardEntitlement; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.event.Broadcast; import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider; @@ -69,8 +67,7 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco final BaseRestClient bulkActionExecutor, final String keyFieldName) { - this(MultilevelPanel.SECOND_LEVEL_ID, - modal, items, columns, actions, bulkActionExecutor, keyFieldName); + this(MultilevelPanel.SECOND_LEVEL_ID, modal, items, columns, actions, bulkActionExecutor, keyFieldName); } public BulkContent( @@ -146,8 +143,8 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco throw new IllegalArgumentException("Invalid bulk action executor"); } - final AbstractAnyRestClient<?> anyRestClient = - AbstractAnyRestClient.class.cast(bulkActionExecutor); + final AbstractAnyRestClient<?> anyRestClient + = AbstractAnyRestClient.class.cast(bulkActionExecutor); if (items.isEmpty() || !(items.iterator().next() instanceof StatusBean)) { throw new IllegalArgumentException("Invalid items"); @@ -205,10 +202,6 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco modal.changeCloseButtonLabel(getString("close", null, "Close"), target); } - final EventDataWrapper data = new EventDataWrapper(); - data.setTarget(target); - send(getPage(), Broadcast.BREADTH, data); - final List<IColumn<T, S>> newColumnList = new ArrayList<>(columns); newColumnList.add(newColumnList.size(), new BulkActionResultColumn<T, S>(res, keyFieldName)); http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java index e2a6686..cb5221a 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java @@ -143,8 +143,10 @@ public abstract class AbstractSearchResultPanel< rows = prefMan.getPaginatorRows(getRequest(), paginatorRowsKey()); setWindowClosedReloadCallback(modal); + setWindowClosedReloadCallback(altDefaultModal); + setWindowClosedReloadCallback(displayAttributeModal); } - + protected abstract DP dataProvider(); protected abstract String paginatorRowsKey(); @@ -247,7 +249,9 @@ public abstract class AbstractSearchResultPanel< updateResultTable(data.isCreate(), data.getRows()); } - data.getTarget().add(container); + if (AbstractSearchResultPanel.this.container.isVisibleInHierarchy()) { + data.getTarget().add(AbstractSearchResultPanel.this.container); + } } super.onEvent(event); } http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java index d02a784..9662753 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java @@ -21,6 +21,7 @@ package org.apache.syncope.client.console.panels; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.rest.BaseRestClient; @@ -214,7 +215,7 @@ public final class AjaxDataTablePanel<T extends Serializable, S> extends DataTab target.add(bulkModal.setContent(new BulkActionModal<>( bulkModal, builder.pageRef, - group.getModelObject(), + new ArrayList<T>(group.getModelObject()), // serialization problem with sublist only new ArrayList<>(builder.columns.subList(1, builder.columns.size() - 1)), builder.bulkActions, @@ -225,13 +226,15 @@ public final class AjaxDataTablePanel<T extends Serializable, S> extends DataTab } else { builder.multiLevelPanel.next("bulk.action", new BulkContent<>( builder.baseModal, - group.getModelObject(), + new ArrayList<T>(group.getModelObject()), // serialization problem with sublist only new ArrayList<>(builder.columns.subList(1, builder.columns.size() - 1)), builder.bulkActions, builder.bulkActionExecutor, builder.itemKeyField), target); } + group.setModelObject(Collections.<T>emptyList()); + target.add(group); } }.setEnabled(builder.isBulkEnabled()).setVisible(builder.isBulkEnabled())); } http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDisplayAttributesModalPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDisplayAttributesModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDisplayAttributesModalPanel.java index baf5f4e..c8022e3 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDisplayAttributesModalPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDisplayAttributesModalPanel.java @@ -35,7 +35,7 @@ public class UserDisplayAttributesModalPanel<T extends Serializable> extends Dis private static final long serialVersionUID = 5194630813773543054L; - public static final String[] USER_DEFAULT_SELECTION = { "key", "username", "status" }; + public static final String[] USER_DEFAULT_SELECTION = { "key", "username", "status", "mustChangePassword" }; public UserDisplayAttributesModalPanel( final BaseModal<T> modal, http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java index 7cb3bb5..443d01e 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java @@ -22,7 +22,7 @@ import java.io.Serializable; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; +import java.util.Collection; import java.util.List; import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; @@ -32,6 +32,7 @@ import org.apache.syncope.client.console.rest.UserRestClient; import org.apache.syncope.client.console.status.StatusModal; import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn; import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AttrColumn; +import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn; import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel; import org.apache.syncope.client.console.wizards.AjaxWizard; @@ -67,6 +68,18 @@ public class UserSearchResultPanel extends AnySearchResultPanel<UserTO> { } @Override + protected Collection<ActionLink.ActionType> getBulkActions() { + final List<ActionLink.ActionType> bulkActions = new ArrayList<>(); + + bulkActions.add(ActionLink.ActionType.MUSTCHANGEPASSWORD); + bulkActions.add(ActionLink.ActionType.DELETE); + bulkActions.add(ActionLink.ActionType.SUSPEND); + bulkActions.add(ActionLink.ActionType.REACTIVATE); + + return bulkActions; + } + + @Override protected List<IColumn<UserTO, String>> getColumns() { final List<IColumn<UserTO, String>> columns = new ArrayList<>(); @@ -74,10 +87,8 @@ public class UserSearchResultPanel extends AnySearchResultPanel<UserTO> { for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_DETAILS_VIEW)) { final Field field = ReflectionUtils.findField(UserTO.class, name); - if ("token".equalsIgnoreCase(name)) { - columns.add(new PropertyColumn<UserTO, String>(new ResourceModel(name, name), name, name)); - } else if (field != null && field.getType().equals(Date.class)) { - columns.add(new PropertyColumn<UserTO, String>(new ResourceModel(name, name), name, name)); + if (field != null && (field.getType().equals(Boolean.class) || field.getType().equals(boolean.class))) { + columns.add(new BooleanPropertyColumn<UserTO>(new ResourceModel(name, name), name, name)); } else { columns.add(new PropertyColumn<UserTO, String>(new ResourceModel(name, name), name, name)); } @@ -121,49 +132,69 @@ public class UserSearchResultPanel extends AnySearchResultPanel<UserTO> { @Override public void onClick(final AjaxRequestTarget target, final UserTO ignore) { - - final IModel<AnyHandler<UserTO>> formModel = - new CompoundPropertyModel<>(new AnyHandler<>(model.getObject())); - altDefaultModal.setFormModel(formModel); - - target.add(altDefaultModal.setContent(new StatusModal<>( - altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false))); - - altDefaultModal.header(new Model<>( - getString("any.edit", new Model<>(new AnyHandler<>(model.getObject()))))); - - altDefaultModal.show(true); + try { + UserRestClient.class.cast(restClient). + mustChangePassword(model.getObject().getETagValue(), model.getObject().getKey()); + info(getString(Constants.OPERATION_SUCCEEDED)); + target.add(container); + } catch (SyncopeClientException e) { + LOG.error("While deleting object {}", model.getObject().getKey(), e); + error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage()); + } + SyncopeConsoleSession.get().getNotificationPanel().refresh(target); } - }, ActionLink.ActionType.MANAGE_RESOURCES, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() { + }, ActionLink.ActionType.MUSTCHANGEPASSWORD, StandardEntitlement.USER_UPDATE).add( + new ActionLink<UserTO>() { private static final long serialVersionUID = -7978723352517770644L; @Override public void onClick(final AjaxRequestTarget target, final UserTO ignore) { - final IModel<AnyHandler<UserTO>> formModel = - new CompoundPropertyModel<>(new AnyHandler<>(model.getObject())); + + final IModel<AnyHandler<UserTO>> formModel + = new CompoundPropertyModel<>(new AnyHandler<>(model.getObject())); altDefaultModal.setFormModel(formModel); target.add(altDefaultModal.setContent(new StatusModal<>( - altDefaultModal, pageRef, formModel.getObject().getInnerObject(), true))); + altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false))); altDefaultModal.header(new Model<>( getString("any.edit", new Model<>(new AnyHandler<>(model.getObject()))))); altDefaultModal.show(true); } - }, ActionLink.ActionType.ENABLE, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() { - - private static final long serialVersionUID = -7978723352517770644L; - - @Override - public void onClick(final AjaxRequestTarget target, final UserTO ignore) { - send(UserSearchResultPanel.this, Broadcast.EXACT, - new AjaxWizard.EditItemActionEvent<>( - new AnyHandler<>(new UserRestClient().read(model.getObject().getKey())), - target)); - } - }, ActionLink.ActionType.EDIT, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() { + }, ActionLink.ActionType.MANAGE_RESOURCES, StandardEntitlement.USER_READ).add( + new ActionLink<UserTO>() { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target, final UserTO ignore) { + final IModel<AnyHandler<UserTO>> formModel = new CompoundPropertyModel<>( + new AnyHandler<>(model. + getObject())); + altDefaultModal.setFormModel(formModel); + + target.add(altDefaultModal.setContent(new StatusModal<>( + altDefaultModal, pageRef, formModel.getObject().getInnerObject(), true))); + + altDefaultModal.header(new Model<>( + getString("any.edit", new Model<>(new AnyHandler<>(model.getObject()))))); + + altDefaultModal.show(true); + } + }, ActionLink.ActionType.ENABLE, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target, final UserTO ignore) { + send(UserSearchResultPanel.this, Broadcast.EXACT, + new AjaxWizard.EditItemActionEvent<>( + new AnyHandler<>(new UserRestClient().read(model.getObject().getKey())), + target)); + } + }, ActionLink.ActionType.EDIT, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() { private static final long serialVersionUID = -7978723352517770644L; http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java index ff4b2fa..b26d31b 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java @@ -23,6 +23,7 @@ import javax.ws.rs.core.GenericType; import javax.ws.rs.core.Response; import org.apache.syncope.client.console.commons.status.StatusBean; import org.apache.syncope.client.console.commons.status.StatusUtils; +import org.apache.syncope.common.lib.patch.BooleanReplacePatchItem; import org.apache.syncope.common.lib.patch.StatusPatch; import org.apache.syncope.common.lib.patch.UserPatch; import org.apache.syncope.common.lib.to.BulkAction; @@ -115,6 +116,13 @@ public class UserRestClient extends AbstractAnyRestClient<UserTO> { return getService(ResourceService.class).readConnObject(resourceName, AnyTypeKind.USER.name(), id); } + public ProvisioningResult<UserTO> mustChangePassword(final String etag, final Long key) { + final UserPatch userPatch = new UserPatch(); + userPatch.setKey(key); + userPatch.setMustChangePassword(new BooleanReplacePatchItem.Builder().value(true).build()); + return update(etag, userPatch); + } + public void suspend(final String etag, final long userKey, final List<StatusBean> statuses) { StatusPatch statusPatch = StatusUtils.buildStatusPatch(statuses, false); statusPatch.setKey(userKey); http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java ---------------------------------------------------------------------- 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 93fda56..9bd19ee 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 @@ -42,6 +42,7 @@ public abstract class ActionLink<T extends Serializable> implements Serializable MAPPING("update"), ACCOUNT_LINK("update"), + MUSTCHANGEPASSWORD("update"), RESET_TIME("update"), CLONE("create"), CREATE("create"), http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java index b56da38..4170ba9 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java @@ -57,6 +57,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel { super.add(new Fragment("panelManageGroups", "emptyFragment", this)); super.add(new Fragment("panelMapping", "emptyFragment", this)); super.add(new Fragment("panelAccountLink", "emptyFragment", this)); + super.add(new Fragment("panelResetPwd", "emptyFragment", this)); super.add(new Fragment("panelResetTime", "emptyFragment", this)); super.add(new Fragment("panelClone", "emptyFragment", this)); super.add(new Fragment("panelCreate", "emptyFragment", this)); @@ -212,6 +213,25 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel { }.setVisible(link.isEnabled(model.getObject()))); break; + case MUSTCHANGEPASSWORD: + fragment = new Fragment("panelResetPwd", "fragmentResetPwd", this); + + fragment.addOrReplace(new IndicatingAjaxLink<Void>("resetPwdLink") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + link.onClick(target, model.getObject()); + } + + @Override + public String getAjaxIndicatorMarkupId() { + return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId(); + } + }.setVisible(link.isEnabled(model.getObject()))); + break; + case RESET_TIME: fragment = new Fragment("panelResetTime", "fragmentResetTime", this); @@ -792,6 +812,10 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel { super.addOrReplace(new Fragment("panelAccountLink", "emptyFragment", this)); break; + case MUSTCHANGEPASSWORD: + super.addOrReplace(new Fragment("panelResetPwd", "emptyFragment", this)); + break; + case RESET_TIME: super.addOrReplace(new Fragment("panelResetTime", "emptyFragment", this)); break; http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html index 78d0927..d8754e6 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html @@ -26,6 +26,7 @@ under the License. </style> </wicket:head> <wicket:panel> + <span wicket:id="panelResetPwd">[plus]</span> <span wicket:id="panelClaim">[plus]</span> <span wicket:id="panelManageResources">[plus]</span> <span wicket:id="panelManageUsers">[plus]</span> @@ -62,6 +63,10 @@ under the License. <span wicket:id="panelZoomIn">[plus]</span> <span wicket:id="panelZoomOut">[plus]</span> + <wicket:fragment wicket:id="fragmentResetPwd"> + <a href="#" wicket:id="resetPwdLink" class="btn"><i class="fa fa-lock" alt="reset password icon" title="Reset password"></i></a> + </wicket:fragment> + <wicket:fragment wicket:id="fragmentClaim"> <a href="#" wicket:id="claimLink" class="btn"><img id="actionLink" src="img/actions/claim.png" alt="claim icon" title="Claim"/></a> </wicket:fragment> http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java index 2fad211..c3edf7c 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java @@ -38,6 +38,7 @@ public class BulkAction extends AbstractBaseBean { @XmlType(name = "bulkActionType") public enum Type { + MUSTCHANGEPASSWORD, DELETE, REACTIVATE, SUSPEND, http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java ---------------------------------------------------------------------- diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java index ca324a8..98f9aae 100644 --- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java +++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java @@ -19,6 +19,7 @@ package org.apache.syncope.core.rest.cxf.service; import java.util.Set; +import javax.ws.rs.BadRequestException; import javax.ws.rs.core.Response; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.AnyOperations; @@ -26,8 +27,10 @@ import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.patch.AnyPatch; import org.apache.syncope.common.lib.patch.AssociationPatch; import org.apache.syncope.common.lib.patch.AttrPatch; +import org.apache.syncope.common.lib.patch.BooleanReplacePatchItem; import org.apache.syncope.common.lib.patch.DeassociationPatch; import org.apache.syncope.common.lib.patch.StatusPatch; +import org.apache.syncope.common.lib.patch.UserPatch; import org.apache.syncope.common.lib.search.SpecialAttr; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.AttrTO; @@ -197,8 +200,8 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch> checkETag(before.getETagValue()); - ProvisioningResult<TO> updated = - getAnyLogic().update(AnyOperations.<TO, P>diff(anyTO, before, false), isNullPriorityAsync()); + ProvisioningResult<TO> updated = getAnyLogic().update(AnyOperations.<TO, P>diff(anyTO, before, false), + isNullPriorityAsync()); return modificationResponse(updated); } @@ -326,6 +329,27 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch> BulkActionResult result = new BulkActionResult(); switch (bulkAction.getType()) { + case MUSTCHANGEPASSWORD: + if (logic instanceof UserLogic) { + for (String key : bulkAction.getTargets()) { + try { + final UserPatch userPatch = new UserPatch(); + userPatch.setKey(Long.valueOf(key)); + userPatch.setMustChangePassword(new BooleanReplacePatchItem.Builder().value(true).build()); + + result.getResults().put( + String.valueOf(((UserLogic) logic).update(userPatch, false).getAny().getKey()), + BulkActionResult.Status.SUCCESS); + } catch (Exception e) { + LOG.error("Error performing delete for user {}", key, e); + result.getResults().put(key, BulkActionResult.Status.FAILURE); + } + } + } else { + throw new BadRequestException(); + } + break; + case DELETE: for (String key : bulkAction.getTargets()) { try { @@ -356,23 +380,29 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch> result.getResults().put(key, BulkActionResult.Status.FAILURE); } } + } else { + throw new BadRequestException(); } break; case REACTIVATE: - for (String key : bulkAction.getTargets()) { - StatusPatch statusPatch = new StatusPatch(); - statusPatch.setKey(Long.valueOf(key)); - statusPatch.setType(StatusPatchType.REACTIVATE); - try { - result.getResults().put( - String.valueOf(((UserLogic) logic). - status(statusPatch, isNullPriorityAsync()).getAny().getKey()), - BulkActionResult.Status.SUCCESS); - } catch (Exception e) { - LOG.error("Error performing reactivate for user {}", key, e); - result.getResults().put(key, BulkActionResult.Status.FAILURE); + if (logic instanceof UserLogic) { + for (String key : bulkAction.getTargets()) { + StatusPatch statusPatch = new StatusPatch(); + statusPatch.setKey(Long.valueOf(key)); + statusPatch.setType(StatusPatchType.REACTIVATE); + try { + result.getResults().put( + String.valueOf(((UserLogic) logic). + status(statusPatch, isNullPriorityAsync()).getAny().getKey()), + BulkActionResult.Status.SUCCESS); + } catch (Exception e) { + LOG.error("Error performing reactivate for user {}", key, e); + result.getResults().put(key, BulkActionResult.Status.FAILURE); + } } + } else { + throw new BadRequestException(); } break; http://git-wip-us.apache.org/repos/asf/syncope/blob/04183d50/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java index b193672..33421ce 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java @@ -77,7 +77,7 @@ public class BulkActionITCase extends AbstractConsoleITCase { assertNotNull(component); wicketTester.clickLink(component.getPageRelativePath() - + ":cells:5:cell:panelManageResources:manageResourcesLink"); + + ":cells:6:cell:panelManageResources:manageResourcesLink"); wicketTester.assertComponent(tabPanel + "alternativeDefaultModal:form:content:status:" + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:" @@ -118,7 +118,7 @@ public class BulkActionITCase extends AbstractConsoleITCase { + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini"); assertNotNull(component); - wicketTester.clickLink(component.getPageRelativePath() + ":cells:5:cell:panelEnable:enableLink"); + wicketTester.clickLink(component.getPageRelativePath() + ":cells:6:cell:panelEnable:enableLink"); wicketTester.assertComponent(tabPanel + "alternativeDefaultModal:form:content:status:" + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:" @@ -153,7 +153,7 @@ public class BulkActionITCase extends AbstractConsoleITCase { + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini"); assertNotNull(component); - wicketTester.clickLink(component.getPageRelativePath() + ":cells:5:cell:panelEnable:enableLink"); + wicketTester.clickLink(component.getPageRelativePath() + ":cells:6:cell:panelEnable:enableLink"); wicketTester.assertComponent(tabPanel + "alternativeDefaultModal:form:content:status:" + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
