Repository: syncope
Updated Branches:
  refs/heads/2_0_X e82f08946 -> ffe91ae55
  refs/heads/master bf0289f14 -> 1a1f7081b


[SYNCOPE-991] move change password feature with granularity to resources 
outside user editing


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/ffe91ae5
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/ffe91ae5
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/ffe91ae5

Branch: refs/heads/2_0_X
Commit: ffe91ae5507c2abdd6656ce158d766b642d4aca6
Parents: e82f089
Author: fmartelli <fabio.marte...@gmail.com>
Authored: Fri Mar 10 12:29:32 2017 +0100
Committer: fmartelli <fabio.marte...@gmail.com>
Committed: Fri Mar 10 12:29:32 2017 +0100

----------------------------------------------------------------------
 .../console/panels/UserDirectoryPanel.java      |  24 +++-
 .../panels/search/SearchClausePanel.java        |   1 +
 .../console/status/AnyStatusDirectoryPanel.java |  40 ++++++-
 .../console/status/ChangePasswordModal.java     | 110 +++++++++++++++++++
 .../client/console/status/StatusModal.java      |   1 +
 .../wicket/markup/html/form/ActionLink.java     |   1 +
 .../markup/html/form/ActionLinksPanel.java      |  25 +++++
 .../console/wizards/any/AnyObjectDetails.java   |   6 +-
 .../wizards/any/AnyObjectWizardBuilder.java     |   4 -
 .../console/wizards/any/AnyWizardBuilder.java   |   4 -
 .../client/console/wizards/any/Details.java     |  12 --
 .../console/wizards/any/GroupDetails.java       |   6 +-
 .../console/wizards/any/GroupWizardBuilder.java |   4 -
 .../client/console/wizards/any/StatusPanel.java |  23 ++--
 .../client/console/wizards/any/UserDetails.java |  40 ++++---
 .../console/wizards/any/UserWizardBuilder.java  |  32 +-----
 .../META-INF/resources/css/syncopeConsole.css   |   4 +
 .../console/status/ChangePasswordModal.html     |  29 +++++
 .../markup/html/form/ActionLinksPanel.html      |   5 +
 .../client/console/wizards/any/Details.html     |   1 -
 .../console/wizards/any/Details.properties      |   1 +
 .../console/wizards/any/Details_it.properties   |   1 +
 .../wizards/any/Details_pt_BR.properties        |   1 +
 .../console/wizards/any/Details_ru.properties   |   3 +-
 .../any/UserDetails$EditUserPasswordPanel.html  |  26 +++++
 .../syncope/fit/console/AnyObjectsITCase.java   |   5 +-
 .../syncope/fit/console/BulkActionITCase.java   |   4 +-
 .../apache/syncope/fit/console/UsersITCase.java |  49 +++++++++
 28 files changed, 367 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
----------------------------------------------------------------------
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 08931f8..80c958f 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
@@ -31,6 +31,7 @@ import 
org.apache.syncope.client.console.notifications.NotificationTasks;
 import org.apache.syncope.client.console.pages.BasePage;
 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.extensions.markup.html.repeater.data.table.ActionColumn;
 import 
org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AttrColumn;
@@ -274,7 +275,28 @@ public class UserDirectoryPanel extends 
AnyDirectoryPanel<UserTO, UserRestClient
                             utilityModal.show(true);
                             target.add(utilityModal);
                         }
-                    }, ActionType.NOTIFICATION_TASKS, 
StandardEntitlement.TASK_LIST);
+                    }, ActionType.NOTIFICATION_TASKS, 
StandardEntitlement.TASK_LIST).add(new ActionLink<UserTO>() {
+
+                        private static final long serialVersionUID = 
-4875218360625971340L;
+
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, 
final UserTO ignore) {
+                            IModel<AnyWrapper<UserTO>> formModel = new 
CompoundPropertyModel<>(
+                                    new AnyWrapper<>(model.getObject()));
+                            displayAttributeModal.setFormModel(formModel);
+
+                            target.add(displayAttributeModal.setContent(new 
ChangePasswordModal(
+                                    displayAttributeModal,
+                                    pageRef,
+                                    new UserWrapper(model.getObject()))));
+
+                            displayAttributeModal.header(new Model<>(
+                                    getString("any.edit", new Model<>(new 
AnyWrapper<>(model.getObject())))));
+
+                            displayAttributeModal.show(true);
+                        }
+                    }, ActionType.PASSWORD_RESET,
+                            new 
StringBuilder().append(StandardEntitlement.USER_UPDATE).toString());
                 }
 
                 return panel.build(componentId, model.getObject());

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
index e4327cb..b94a284 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
@@ -429,6 +429,7 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
         final AjaxDropDownChoicePanel<SearchClause.Type> type = new 
AjaxDropDownChoicePanel<>(
                 "type", "type", new 
PropertyModel<SearchClause.Type>(searchClause, "type"));
         
type.setChoices(types).hideLabel().setRequired(required).setOutputMarkupId(true);
+        type.setNullValid(false);
         type.getField().add(new 
IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
             private static final long serialVersionUID = -1107858522700306810L;

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
index fee2de8..3cbcfdc 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
@@ -30,6 +30,7 @@ import 
org.apache.syncope.client.console.commons.status.StatusBean;
 import org.apache.syncope.client.console.commons.status.StatusUtils;
 import org.apache.syncope.client.console.panels.DirectoryPanel;
 import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
+import org.apache.syncope.client.console.panels.ConnObjectDetails;
 import org.apache.syncope.client.console.panels.ModalPanel;
 import org.apache.syncope.client.console.panels.MultilevelPanel;
 import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
@@ -37,14 +38,17 @@ import 
org.apache.syncope.client.console.rest.AnyObjectRestClient;
 import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
 import org.apache.syncope.client.console.rest.UserRestClient;
-import 
org.apache.syncope.client.console.status.AnyStatusDirectoryPanel.AttributableStatusProvider;
+import 
org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
 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.ActionLinksPanel;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
 import 
org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
 import 
org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
@@ -53,6 +57,7 @@ import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.StringResourceModel;
 
 public class AnyStatusDirectoryPanel
@@ -69,6 +74,8 @@ public class AnyStatusDirectoryPanel
 
     private final boolean statusOnly;
 
+    private final ResourceRestClient resourceRestClient = new 
ResourceRestClient();
+
     public AnyStatusDirectoryPanel(
             final BaseModal<?> baseModal,
             final MultilevelPanel multiLevelPanelRef,
@@ -152,6 +159,37 @@ public class AnyStatusDirectoryPanel
             }
         });
 
+        columns.add(new ActionColumn<StatusBean, String>(new 
ResourceModel("actions", "")) {
+
+            private static final long serialVersionUID = 3372107192677413965L;
+
+            @Override
+            public ActionLinksPanel<StatusBean> getActions(
+                    final String componentId, final IModel<StatusBean> model) {
+
+                final ActionLinksPanel.Builder<StatusBean> panel = 
ActionLinksPanel.builder();
+
+                panel.add(new ActionLink<StatusBean>() {
+
+                    private static final long serialVersionUID = 
-7978723352517770645L;
+
+                    @Override
+                    protected boolean statusCondition(final StatusBean bean) {
+                        return bean.getConnObjectLink() != null;
+                    }
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final 
StatusBean bean) {
+                        multiLevelPanelRef.next(bean.getResourceName(),
+                                new 
ConnObjectDetails(resourceRestClient.readConnObject(
+                                        bean.getResourceName(), 
anyTO.getType(), anyTO.getKey())), target);
+                        target.add(multiLevelPanelRef);
+                    }
+                }, ActionLink.ActionType.VIEW, 
StandardEntitlement.RESOURCE_GET_CONNOBJECT);
+
+                return panel.build(componentId, model.getObject());
+            }
+        });
         return columns;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
new file mode 100644
index 0000000..dff996f
--- /dev/null
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
@@ -0,0 +1,110 @@
+/*
+ * 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.status;
+
+import java.util.ArrayList;
+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.commons.status.StatusBean;
+import org.apache.syncope.client.console.panels.AbstractModalPanel;
+import org.apache.syncope.client.console.panels.ListViewPanel;
+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.wizards.any.AnyWrapper;
+import org.apache.syncope.client.console.wizards.any.PasswordPanel;
+import org.apache.syncope.client.console.wizards.any.StatusPanel;
+import org.apache.syncope.client.console.wizards.any.UserWrapper;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.util.ListModel;
+
+public class ChangePasswordModal extends 
AbstractModalPanel<AnyWrapper<UserTO>> {
+
+    private static final long serialVersionUID = 6257389301592059194L;
+
+    private final UserRestClient userRestClient = new UserRestClient();
+
+    private final IModel<List<StatusBean>> statusModel;
+
+    private final UserWrapper wrapper;
+
+    public ChangePasswordModal(
+            final BaseModal<AnyWrapper<UserTO>> baseModal,
+            final PageReference pageReference,
+            final UserWrapper wrapper) {
+        super(baseModal, pageReference);
+
+        this.wrapper = wrapper;
+
+        final PasswordPanel passwordPanel = new PasswordPanel("passwordPanel", 
wrapper, false);
+        passwordPanel.setOutputMarkupId(true);
+        add(passwordPanel);
+
+        statusModel = new ListModel<>(new ArrayList<StatusBean>());
+        StatusPanel statusPanel = new StatusPanel("status", 
wrapper.getInnerObject(), statusModel, pageReference);
+        
statusPanel.setCheckAvailability(ListViewPanel.CheckAvailability.AVAILABLE);
+        add(statusPanel.setRenderBodyOnly(true));
+    }
+
+    @Override
+    public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+        final UserTO inner = wrapper.getInnerObject();
+
+        try {
+            if (StringUtils.isBlank(inner.getPassword()) || 
statusModel.getObject().isEmpty()) {
+                
SyncopeConsoleSession.get().error(getString(Constants.OPERATION_ERROR));
+            } else {
+                final List<String> resources = new ArrayList<String>();
+                boolean isOnSyncope = false;
+                for (StatusBean sb : statusModel.getObject()) {
+                    if (sb.getResourceName().equals(Constants.SYNCOPE)) {
+                        isOnSyncope = true;
+                    } else {
+                        resources.add(sb.getResourceName());
+                    }
+                }
+
+                final UserPatch patch = new UserPatch();
+                patch.setKey(inner.getKey());
+
+                PasswordPatch passwordPatch = new PasswordPatch.Builder().
+                        
value(inner.getPassword()).onSyncope(isOnSyncope).resources(resources).build();
+                patch.setPassword(passwordPatch);
+
+                userRestClient.update(inner.getETagValue(), patch);
+                
SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                modal.show(false);
+                modal.close(target);
+            }
+        } catch (Exception e) {
+            LOG.error("While updating password for user {}", inner, e);
+            
SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                    ? e.getClass().getName()
+                    : e.getMessage());
+        }
+        super.onSubmit(target, form);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
index 9e04151..1059919 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
@@ -45,6 +45,7 @@ public abstract class StatusModal<T extends Serializable> 
extends Panel implemen
         super(BaseModal.CONTENT_ID);
 
         final MultilevelPanel mlp = new MultilevelPanel("status");
+        mlp.setOutputMarkupId(true);
         this.directoryPanel = getStatusDirectoryPanel(
                 mlp, baseModal, pageReference, entity, itemKeyFieldName, 
statusOnly);
         add(mlp.setFirstLevel(this.directoryPanel));

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/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 78e7292..2fef62f 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
@@ -62,6 +62,7 @@ public abstract class ActionLink<T extends Serializable> 
implements Serializable
         SEARCH("search"),
         DELETE("delete"),
         EXECUTE("execute"),
+        PASSWORD_RESET("update"),
         DRYRUN("execute"),
         CLAIM("claim"),
         SELECT("read"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/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 93025a3..9e2bd0c 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
@@ -77,6 +77,7 @@ public final class ActionLinksPanel<T extends Serializable> 
extends Panel {
         super.add(new Fragment("panelSearch", "emptyFragment", this));
         super.add(new Fragment("panelDelete", "emptyFragment", this));
         super.add(new Fragment("panelExecute", "emptyFragment", this));
+        super.add(new Fragment("panelPasswordReset", "emptyFragment", this));
         super.add(new Fragment("panelDryRun", "emptyFragment", this));
         super.add(new Fragment("panelSelect", "emptyFragment", this));
         super.add(new Fragment("panelClose", "emptyFragment", this));
@@ -596,6 +597,26 @@ public final class ActionLinksPanel<T extends 
Serializable> extends Panel {
                 }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
+            case PASSWORD_RESET:
+                fragment = new Fragment("panelPasswordReset", 
"fragmentPasswordReset", this);
+
+                fragment.addOrReplace(new 
IndicatingAjaxLink<Void>("passwordResetLink") {
+
+                    private static final long serialVersionUID = 
-7978723352517770644L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        link.onClick(target, model.getObject());
+                    }
+
+                    @Override
+                    public String getAjaxIndicatorMarkupId() {
+                        return disableIndicator || !link.isIndicatorEnabled()
+                                ? StringUtils.EMPTY : 
super.getAjaxIndicatorMarkupId();
+                    }
+                }.setVisible(link.isEnabled(model.getObject())));
+                break;
+
             case DRYRUN:
                 fragment = new Fragment("panelDryRun", "fragmentDryRun", this);
 
@@ -1216,6 +1237,10 @@ public final class ActionLinksPanel<T extends 
Serializable> extends Panel {
                 super.addOrReplace(new Fragment("panelExecute", 
"emptyFragment", this));
                 break;
 
+            case PASSWORD_RESET:
+                super.addOrReplace(new Fragment("panelPasswordReset", 
"emptyFragment", this));
+                break;
+
             case DRYRUN:
                 super.addOrReplace(new Fragment("panelDryRun", 
"emptyFragment", this));
                 break;

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectDetails.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectDetails.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectDetails.java
index dc48586..91ed3a5 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectDetails.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectDetails.java
@@ -18,12 +18,9 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
-import java.util.List;
-import org.apache.syncope.client.console.commons.status.StatusBean;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.wicket.PageReference;
-import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.PropertyModel;
 
 public class AnyObjectDetails extends Details<AnyObjectTO> {
@@ -32,12 +29,11 @@ public class AnyObjectDetails extends Details<AnyObjectTO> {
 
     public AnyObjectDetails(
             final AnyWrapper<AnyObjectTO> wrapper,
-            final IModel<List<StatusBean>> statusModel,
             final boolean templateMode,
             final boolean includeStatusPanel,
             final PageReference pageRef) {
 
-        super(wrapper, statusModel, templateMode, includeStatusPanel, pageRef);
+        super(wrapper, templateMode, includeStatusPanel, pageRef);
 
         AnyObjectTO anyObjectTO = wrapper.getInnerObject();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
index 3eb30ea..5d925df 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java
@@ -19,9 +19,7 @@
 package org.apache.syncope.client.console.wizards.any;
 
 import java.io.Serializable;
-import java.util.Collections;
 import java.util.List;
-import org.apache.syncope.client.console.commons.status.StatusBean;
 import org.apache.syncope.client.console.layout.AnyObjectForm;
 import org.apache.syncope.client.console.layout.AnyObjectFormLayoutInfo;
 import org.apache.syncope.client.console.rest.AnyObjectRestClient;
@@ -31,7 +29,6 @@ import org.apache.syncope.common.lib.patch.AnyObjectPatch;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.wicket.PageReference;
-import org.apache.wicket.model.util.ListModel;
 
 public class AnyObjectWizardBuilder extends AnyWizardBuilder<AnyObjectTO> 
implements AnyObjectForm {
 
@@ -74,7 +71,6 @@ public class AnyObjectWizardBuilder extends 
AnyWizardBuilder<AnyObjectTO> implem
     protected Details<AnyObjectTO> addOptionalDetailsPanel(final 
AnyWrapper<AnyObjectTO> modelObject) {
         return new AnyObjectDetails(
                 modelObject,
-                new ListModel<>(Collections.<StatusBean>emptyList()),
                 mode == AjaxWizard.Mode.TEMPLATE,
                 modelObject.getInnerObject().getKey() != null, pageRef);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index 4df08c0..1253f20 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -18,9 +18,7 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
-import java.util.Collections;
 import java.util.List;
-import org.apache.syncope.client.console.commons.status.StatusBean;
 import org.apache.syncope.client.console.layout.AbstractAnyFormLayout;
 import org.apache.syncope.client.console.layout.AnyForm;
 import org.apache.syncope.client.console.layout.AnyObjectFormLayoutInfo;
@@ -33,7 +31,6 @@ import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.extensions.wizard.WizardModel;
-import org.apache.wicket.model.util.ListModel;
 
 public abstract class AnyWizardBuilder<A extends AnyTO> extends 
AjaxWizardBuilder<AnyWrapper<A>> {
 
@@ -163,7 +160,6 @@ public abstract class AnyWizardBuilder<A extends AnyTO> 
extends AjaxWizardBuilde
         if (modelObject.getInnerObject().getKey() != null) {
             return new Details<>(
                     modelObject,
-                    new ListModel<>(Collections.<StatusBean>emptyList()),
                     mode == AjaxWizard.Mode.TEMPLATE,
                     true,
                     pageRef);

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/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 8e1ccfb..61e4884 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,10 +19,8 @@
 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.commons.status.StatusBean;
 import org.apache.syncope.client.console.rest.RealmRestClient;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
@@ -31,7 +29,6 @@ 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.model.IModel;
 import org.apache.wicket.model.PropertyModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,13 +41,10 @@ public class Details<T extends AnyTO> extends WizardStep {
 
     protected final PageReference pageRef;
 
-    protected final StatusPanel statusPanel;
-
     private final FieldPanel<String> realm;
 
     public Details(
             final AnyWrapper<T> wrapper,
-            final IModel<List<StatusBean>> statusModel,
             final boolean templateMode,
             final boolean includeStatusPanel,
             final PageReference pageRef) {
@@ -78,12 +72,6 @@ public class Details<T extends AnyTO> extends WizardStep {
             }, new ArrayList<String>()));
         }
         add(realm);
-
-        statusPanel = new StatusPanel("status", inner, statusModel, pageRef);
-
-        add(statusPanel.setEnabled(includeStatusPanel).
-                setVisible(includeStatusPanel).setRenderBodyOnly(true));
-
         add(getGeneralStatusInformation("generalStatusInformation", inner).
                 
setEnabled(includeStatusPanel).setVisible(includeStatusPanel).setRenderBodyOnly(true));
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
index 9c19541..33b7442 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
@@ -18,12 +18,9 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
-import java.util.List;
-import org.apache.syncope.client.console.commons.status.StatusBean;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.wicket.PageReference;
-import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.PropertyModel;
 
 public class GroupDetails extends Details<GroupTO> {
@@ -32,12 +29,11 @@ public class GroupDetails extends Details<GroupTO> {
 
     public GroupDetails(
             final GroupWrapper wrapper,
-            final IModel<List<StatusBean>> statusModel,
             final boolean templateMode,
             final boolean includeStatusPanel,
             final PageReference pageRef) {
 
-        super(wrapper, statusModel, templateMode, includeStatusPanel, pageRef);
+        super(wrapper, templateMode, includeStatusPanel, pageRef);
 
         GroupTO groupTO = GroupWrapper.class.cast(wrapper).getInnerObject();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
index 4c6ccf5..6c1e166 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java
@@ -19,9 +19,7 @@
 package org.apache.syncope.client.console.wizards.any;
 
 import java.io.Serializable;
-import java.util.Collections;
 import java.util.List;
-import org.apache.syncope.client.console.commons.status.StatusBean;
 import org.apache.syncope.client.console.layout.GroupForm;
 import org.apache.syncope.client.console.layout.GroupFormLayoutInfo;
 import org.apache.syncope.client.console.rest.GroupRestClient;
@@ -32,7 +30,6 @@ import org.apache.syncope.common.lib.patch.GroupPatch;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.wicket.PageReference;
-import org.apache.wicket.model.util.ListModel;
 
 public class GroupWizardBuilder extends AnyWizardBuilder<GroupTO> implements 
GroupForm {
 
@@ -90,7 +87,6 @@ public class GroupWizardBuilder extends 
AnyWizardBuilder<GroupTO> implements Gro
     protected Details<GroupTO> addOptionalDetailsPanel(final 
AnyWrapper<GroupTO> modelObject) {
         return new GroupDetails(
                 GroupWrapper.class.cast(modelObject),
-                new ListModel<>(Collections.<StatusBean>emptyList()),
                 mode == AjaxWizard.Mode.TEMPLATE,
                 modelObject.getInnerObject().getKey() != null, pageRef);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
index c73ff4d..4ce8868 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
@@ -77,7 +77,7 @@ public class StatusPanel extends Panel {
                         return Pair.of(null, input);
                     }
 
-                }, new ArrayList<Pair<ConnObjectTO, ConnObjectWrapper>>()), 
pageRef);
+                }, new ArrayList<Pair<ConnObjectTO, ConnObjectWrapper>>()), 
pageRef, false);
     }
 
     public <T extends AnyTO> StatusPanel(
@@ -88,14 +88,15 @@ public class StatusPanel extends Panel {
             final PageReference pageRef) {
         super(id);
         statusUtils = new StatusUtils();
-        init(any, model, connObjects, pageRef);
+        init(any, model, connObjects, pageRef, true);
     }
 
     private void init(
             final AnyTO any,
             final IModel<List<StatusBean>> model,
             final List<Pair<ConnObjectTO, ConnObjectWrapper>> connObjects,
-            final PageReference pageRef) {
+            final PageReference pageRef,
+            final boolean enableConnObjectLink) {
 
         final List<StatusBean> statusBeans = new 
ArrayList<>(connObjects.size() + 1);
         initialStatusBeanMap = new LinkedHashMap<>(connObjects.size() + 1);
@@ -153,17 +154,17 @@ public class StatusPanel extends Panel {
         builder.setModel(model);
         builder.setItems(statusBeans);
         builder.includes("resourceName", "connObjectLink", "status");
-        builder.withChecks(ListViewPanel.CheckAvailability.DISABLED);
+        builder.withChecks(ListViewPanel.CheckAvailability.NONE);
         builder.setReuseItem(false);
 
-        builder.addAction(new ActionLink<StatusBean>() {
+        final ActionLink<StatusBean> connObjectLink = new 
ActionLink<StatusBean>() {
 
             private static final long serialVersionUID = -3722207913631435501L;
 
             @Override
             protected boolean statusCondition(final StatusBean bean) {
-                final Pair<ConnObjectTO, ConnObjectTO> pair =
-                        getConnObjectTO(bean.getAnyKey(), 
bean.getResourceName(), connObjects);
+                final Pair<ConnObjectTO, ConnObjectTO> pair
+                        = getConnObjectTO(bean.getAnyKey(), 
bean.getResourceName(), connObjects);
 
                 return pair != null && pair.getRight() != null;
             }
@@ -172,7 +173,13 @@ public class StatusPanel extends Panel {
             public void onClick(final AjaxRequestTarget target, final 
StatusBean bean) {
                 mlp.next(bean.getResourceName(), new RemoteAnyPanel(bean, 
connObjects), target);
             }
-        }, ActionLink.ActionType.VIEW, 
StandardEntitlement.RESOURCE_GET_CONNOBJECT);
+        };
+
+        if (!enableConnObjectLink) {
+            connObjectLink.disable();
+        }
+
+        builder.addAction(connObjectLink, ActionLink.ActionType.VIEW, 
StandardEntitlement.RESOURCE_GET_CONNOBJECT);
 
         listViewPanel = 
ListViewPanel.class.cast(builder.build(MultilevelPanel.FIRST_LEVEL_ID));
         mlp.setFirstLevel(listViewPanel);

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java
index 8dbfcff..f300687 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java
@@ -19,9 +19,6 @@
 package org.apache.syncope.client.console.wizards.any;
 
 import java.util.Collections;
-import java.util.List;
-import org.apache.syncope.client.console.commons.status.StatusBean;
-import org.apache.syncope.client.console.panels.ListViewPanel;
 import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.tabs.Accordion;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.to.UserTO;
@@ -32,8 +29,8 @@ import org.apache.wicket.ajax.markup.html.AjaxLink;
 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.basic.Label;
 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.ResourceModel;
@@ -46,12 +43,11 @@ public class UserDetails extends Details<UserTO> {
 
     public UserDetails(
             final UserWrapper wrapper,
-            final IModel<List<StatusBean>> statusModel,
             final boolean templateMode,
             final boolean includeStatusPanel,
             final boolean showPasswordManagement,
             final PageReference pageRef) {
-        super(wrapper, statusModel, templateMode, includeStatusPanel, pageRef);
+        super(wrapper, templateMode, includeStatusPanel, pageRef);
 
         final UserTO userTO = wrapper.getInnerObject();
         // ------------------------
@@ -80,7 +76,7 @@ public class UserDetails extends Details<UserTO> {
 
             @Override
             public Panel getPanel(final String panelId) {
-                PasswordPanel panel = new PasswordPanel(panelId, wrapper, 
templateMode);
+                EditUserPasswordPanel panel = new 
EditUserPasswordPanel(panelId, wrapper, templateMode);
                 panel.setEnabled(model.getObject() >= 0);
                 return panel;
             }
@@ -103,17 +99,8 @@ public class UserDetails extends Details<UserTO> {
                     @Override
                     public void onClick(final AjaxRequestTarget target) {
                         model.setObject(model.getObject() == 0 ? -1 : 0);
-
-                        boolean enable = model.getObject() >= 0;
-
-                        if (statusPanel.isVisibleInHierarchy()) {
-                            statusPanel.setCheckAvailability(enable
-                                    ? ListViewPanel.CheckAvailability.AVAILABLE
-                                    : 
ListViewPanel.CheckAvailability.DISABLED);
-                        }
-
                         Component passwordPanel = 
getParent().get(PASSWORD_CONTENT_PATH);
-                        passwordPanel.setEnabled(enable);
+                        passwordPanel.setEnabled(model.getObject() >= 0);
                         target.add(passwordPanel);
                     }
                 }.setBody(new ResourceModel("password.change", "Change 
password ..."));
@@ -130,4 +117,23 @@ public class UserDetails extends Details<UserTO> {
     protected AnnotatedBeanPanel getGeneralStatusInformation(final String id, 
final UserTO anyTO) {
         return new UserInformationPanel(id, anyTO);
     }
+
+    public static class EditUserPasswordPanel extends Panel {
+
+        private static final long serialVersionUID = -8198836979773590078L;
+
+        public EditUserPasswordPanel(
+                final String id,
+                final UserWrapper wrapper,
+                final boolean templateMode) {
+            super(id);
+            setOutputMarkupId(true);
+            add(new Label("warning", new ResourceModel(
+                    "password.change.warning",
+                    "Password value will be sent to all associated 
resources")));
+
+            add(new PasswordPanel("passwordPanel", wrapper, templateMode));
+        }
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index 11078e7..0b2652c 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -19,24 +19,18 @@
 package org.apache.syncope.client.console.wizards.any;
 
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.commons.status.StatusBean;
-import org.apache.syncope.client.console.commons.status.StatusUtils;
 import org.apache.syncope.client.console.layout.UserForm;
 import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
 import org.apache.syncope.client.console.rest.UserRestClient;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.common.lib.AnyOperations;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
 import org.apache.syncope.common.lib.patch.UserPatch;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.PageReference;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.util.ListModel;
 
 public class UserWizardBuilder extends AnyWizardBuilder<UserTO> implements 
UserForm {
 
@@ -44,8 +38,6 @@ public class UserWizardBuilder extends 
AnyWizardBuilder<UserTO> implements UserF
 
     private final UserRestClient userRestClient = new UserRestClient();
 
-    private final IModel<List<StatusBean>> statusModel;
-
     public UserWizardBuilder(
             final UserTO userTO,
             final List<String> anyTypeClasses,
@@ -53,7 +45,6 @@ public class UserWizardBuilder extends 
AnyWizardBuilder<UserTO> implements UserF
             final PageReference pageRef) {
 
         super(new UserWrapper(userTO), anyTypeClasses, formLayoutInfo, 
pageRef);
-        statusModel = new ListModel<>(new ArrayList<StatusBean>());
     }
 
     @Override
@@ -68,20 +59,10 @@ public class UserWizardBuilder extends 
AnyWizardBuilder<UserTO> implements UserF
         } else {
             UserPatch patch = AnyOperations.diff(inner, 
getOriginalItem().getInnerObject(), false);
 
-            Set<String> origResourceSet = 
getOriginalItem().getInnerObject().getResources();
-            Set<String> newResourceSet = new HashSet<>(inner.getResources());
-
-            newResourceSet.removeAll(origResourceSet);
-            for (StatusBean sb : statusModel.getObject()) {
-                newResourceSet.remove(sb.getResourceName());
-            }
-
-            for (String res : newResourceSet) {
-                statusModel.getObject().add(new StatusBean(inner, res));
-            }
-
-            if (!statusModel.getObject().isEmpty()) {
-                
patch.setPassword(StatusUtils.buildPasswordPatch(inner.getPassword(), 
statusModel.getObject()));
+            if (StringUtils.isNotBlank(inner.getPassword())) {
+                PasswordPatch passwordPatch = new PasswordPatch.Builder().
+                        
value(inner.getPassword()).onSyncope(true).resources(inner.getResources()).build();
+                patch.setPassword(passwordPatch);
             }
 
             // update just if it is changed
@@ -100,7 +81,7 @@ public class UserWizardBuilder extends 
AnyWizardBuilder<UserTO> implements UserF
     protected Details<UserTO> addOptionalDetailsPanel(final AnyWrapper<UserTO> 
modelObject) {
 
         return new UserDetails(
-                UserWrapper.class.cast(modelObject), statusModel, mode == 
AjaxWizard.Mode.TEMPLATE,
+                UserWrapper.class.cast(modelObject), mode == 
AjaxWizard.Mode.TEMPLATE,
                 modelObject.getInnerObject().getKey() != null,
                 
UserFormLayoutInfo.class.cast(formLayoutInfo).isPasswordManagement(),
                 pageRef);
@@ -115,7 +96,6 @@ public class UserWizardBuilder extends 
AnyWizardBuilder<UserTO> implements UserF
     @Override
     public UserWizardBuilder setItem(final AnyWrapper<UserTO> item) {
         super.setItem(item == null ? null : new 
UserWrapper(item.getInnerObject()));
-        statusModel.getObject().clear();
         return this;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css 
b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index 0ad7824..8089d2c 100644
--- 
a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ 
b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -1103,4 +1103,8 @@ div.background-footer {
 .logviewer-btn {
   padding: 0px 16px 20px 0px;
   float: right;
+}
+
+div#editUserChangePassword > label {
+  color: #e00000;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/resources/org/apache/syncope/client/console/status/ChangePasswordModal.html
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/status/ChangePasswordModal.html
 
b/client/console/src/main/resources/org/apache/syncope/client/console/status/ChangePasswordModal.html
new file mode 100644
index 0000000..41fbcd8
--- /dev/null
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/status/ChangePasswordModal.html
@@ -0,0 +1,29 @@
+<!--
+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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
+  <wicket:panel>
+    <div class="panel-group box-group">
+      <wicket:child/>
+    </div>
+    <fieldset class="input-group">
+      <span wicket:id="passwordPanel">[passwordPanel]</span>
+    </fieldset>
+    <span wicket:id="status">[Status]</span>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/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 2106460..9c12554 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
@@ -33,6 +33,7 @@ under the License.
     <span wicket:id="panelManageGroups">[plus]</span>
     <span wicket:id="panelDryRun">[plus]</span>
     <span wicket:id="panelExecute">[plus]</span>
+    <span wicket:id="panelPasswordReset">[plus]</span>
     <span wicket:id="panelEnable">[plus]</span>
     <span wicket:id="panelSearch">[plus]</span>
     <span wicket:id="panelNotFound">[plus]</span>
@@ -194,6 +195,10 @@ under the License.
       <a href="#" wicket:id="executeLink" class="btn"><i class="fa fa-gear" 
alt="execute icon" title="Execute"></i></a>
     </wicket:fragment>
 
+    <wicket:fragment wicket:id="fragmentPasswordReset">
+      <a href="#" wicket:id="passwordResetLink" class="btn"><i class="fa 
fa-key" alt="password reset icon" title="Password reset"></i></a>
+    </wicket:fragment>
+
     <wicket:fragment wicket:id="fragmentSelect">
       <a href="#" wicket:id="selectLink" class="btn"><i class="glyphicon 
glyphicon-ok"></i></a>
     </wicket:fragment>

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html
 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html
index b8ec7ca..f9b03c8 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.html
@@ -25,7 +25,6 @@ under the License.
           <span wicket:id="destinationRealm">[DESTINATION REALM]</span>
         </div>
         <wicket:child/>
-        <span wicket:id="status">[STATUS]</span>
       </div>
       <div class="details-footer">
         <span wicket:id="generalStatusInformation">[GENERAL STATUS 
INFORMATION]</span>

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.properties
index 7366c21..ad8805e 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.properties
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details.properties
@@ -18,5 +18,6 @@ username=Username
 password=Password
 confirmPassword=Password (confirm)
 password.change=Password management
+password.change.warning=Please note, password value will be sent to all 
associated resources, including the internal storage!
 storePasswordInSyncope=Store password in Syncope
 destinationRealm=Destination realm

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_it.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_it.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_it.properties
index b090895..a65883e 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_it.properties
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_it.properties
@@ -18,5 +18,6 @@ username=Username
 password=Password
 confirmPassword=Password (conferma)
 password.change=Gestisci password
+password.change.warning=Attenzione, la password sar\u00e0 inviata a tutte le 
risorse associate, incluso lo torage interno!
 storePasswordInSyncope=Salva password in Syncope
 destinationRealm=Realm di destinazione

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_pt_BR.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_pt_BR.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_pt_BR.properties
index 5a6f1a4..c081de1 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_pt_BR.properties
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_pt_BR.properties
@@ -18,5 +18,6 @@ username=Nome do Usu\u00e1rio
 password=Senha
 confirmPassword=Senha (confirmar)
 password.change=Gest\u00e3o password
+password.change.warning=Please note, password value will be sent to all 
associated resources, including the internal storage!
 storePasswordInSyncope=Salvar senha in Syncope
 destinationRealm=Destination realm

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_ru.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_ru.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_ru.properties
index c8fd227..581f189 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_ru.properties
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Details_ru.properties
@@ -17,6 +17,7 @@
 username=\u0418\u043c\u044f 
\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
 password=\u041f\u0430\u0440\u043e\u043b\u044c
 confirmPassword=\u041f\u0430\u0440\u043e\u043b\u044c 
(\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435)
-password.change=\u0421\u043c\u0435\u043d\u0438\u0442\u044c 
\u043f\u0430\u0440\u043e\u043b\u044c ...
+password.change=\u0421\u043c\u0435\u043d\u0438\u0442\u044c 
\u043f\u0430\u0440\u043e\u043b\u044c
+password.change.warning=Please note, password value will be sent to all 
associated resources, including the internal storage!
 storePasswordInSyncope=\u0425\u0440\u0430\u043d\u0438\u0442\u044c 
\u043f\u0430\u0440\u043e\u043b\u044c \u0432 Syncope
 destinationRealm=\u041e\u0431\u043b\u0430\u0441\u0442\u044c 
\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/UserDetails$EditUserPasswordPanel.html
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/UserDetails$EditUserPasswordPanel.html
 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/UserDetails$EditUserPasswordPanel.html
new file mode 100644
index 0000000..0918113
--- /dev/null
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/UserDetails$EditUserPasswordPanel.html
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
+  <wicket:panel>
+    <div id="editUserChangePassword">
+      <label wicket:id="warning">[warning]</label>
+      <div wicket:id="passwordPanel">[change password panel]</div>
+    </div>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java
index e7f7d89..b6dddcd 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java
@@ -88,10 +88,7 @@ public class AnyObjectsITCase extends AbstractConsoleITCase {
         assertNotNull(component);
 
         TESTER.clickLink(component.getPageRelativePath() + 
":cells:4:cell:panelEdit:editLink");
-
-        TESTER.assertComponent(TAB_PANEL + 
"outerObjectsRepeater:0:outer:form:content:form:view:status:"
-                + 
"resources:firstLevelContainer:first:container:content:group:beans:0:fields:0", 
ListItem.class);
-
+        
         FormTester formTester = TESTER.newFormTester(TAB_PANEL + 
"outerObjectsRepeater:0:outer:form:content:form");
         assertNotNull(formTester);
         formTester.submit("buttons:next");

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/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 ef55a9b..026c85a 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
@@ -163,7 +163,7 @@ public class BulkActionITCase extends AbstractConsoleITCase 
{
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertLabel(TAB_PANEL + 
"outerObjectsRepeater:1:outer:form:content:status:"
-                + 
"secondLevelContainer:second:container:selectedObjects:body:rows:1:cells:3:cell",
 "SUCCESS");
+                + 
"secondLevelContainer:second:container:selectedObjects:body:rows:1:cells:4:cell",
 "SUCCESS");
 
         TESTER.
                 executeAjaxEvent(TAB_PANEL
@@ -214,7 +214,7 @@ public class BulkActionITCase extends AbstractConsoleITCase 
{
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertLabel(TAB_PANEL + 
"outerObjectsRepeater:1:outer:form:content:status:"
-                + 
"secondLevelContainer:second:container:selectedObjects:body:rows:1:cells:3:cell",
 "SUCCESS");
+                + 
"secondLevelContainer:second:container:selectedObjects:body:rows:1:cells:4:cell",
 "SUCCESS");
 
         TESTER.
                 executeAjaxEvent(TAB_PANEL

http://git-wip-us.apache.org/repos/asf/syncope/blob/ffe91ae5/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
----------------------------------------------------------------------
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 2631395..81b7dfe 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
@@ -338,4 +338,53 @@ public class UsersITCase extends AbstractConsoleITCase {
                 + "form:view:plainSchemas:tabs:0:body:content:schemas:8:panel:"
                 + "multiValueContainer:innerForm:content:view:0:panel:field", 
cal.getTime());
     }
+
+    @Test
+    public void changePassword() {
+        TESTER.cleanupFeedbackMessages();
+
+        TESTER.clickLink("body:realmsLI:realms");
+        
TESTER.clickLink("body:content:body:container:content:tabbedPanel:tabs-container:tabs:1:link");
+
+        Component component = findComponentByProp("username", CONTAINER
+                + 
":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", 
"vivaldi");
+        assertNotNull(component);
+
+        TESTER.clickLink(component.getPageRelativePath() + 
":cells:6:cell:panelPasswordReset:passwordResetLink");
+        TESTER.assertLabel(TAB_PANEL + 
"outerObjectsRepeater:2:outer:form:content:status:resources:"
+                + 
"firstLevelContainer:first:container:content:group:beans:0:fields:0:field", 
"syncope");
+
+        FormTester formTester = TESTER.newFormTester(TAB_PANEL + 
"outerObjectsRepeater:2:outer:form");
+        
formTester.setValue("content:passwordPanel:passwordInnerForm:password:passwordField",
 "Password345");
+        
formTester.setValue("content:passwordPanel:passwordInnerForm:confirmPassword:passwordField",
 "Password345");
+        
formTester.select("content:status:resources:firstLevelContainer:first:container:content:group",
 0);
+
+        TESTER.executeAjaxEvent(
+                TAB_PANEL + 
"outerObjectsRepeater:2:outer:dialog:footer:inputs:0:submit", 
Constants.ON_CLICK);
+
+        TESTER.assertInfoMessages("Operation executed successfully");
+        TESTER.cleanupFeedbackMessages();
+
+        TESTER.clickLink("body:realmsLI:realms");
+        
TESTER.clickLink("body:content:body:container:content:tabbedPanel:tabs-container:tabs:1:link");
+
+        component = findComponentByProp("username", CONTAINER
+                + 
":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", 
"vivaldi");
+        assertNotNull(component);
+
+        TESTER.clickLink(component.getPageRelativePath() + 
":cells:6:cell:panelPasswordReset:passwordResetLink");
+        TESTER.assertLabel(TAB_PANEL + 
"outerObjectsRepeater:2:outer:form:content:status:resources:"
+                + 
"firstLevelContainer:first:container:content:group:beans:0:fields:0:field", 
"syncope");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + 
"outerObjectsRepeater:2:outer:form");
+        
formTester.setValue("content:passwordPanel:passwordInnerForm:password:passwordField",
 "Password123");
+        
formTester.setValue("content:passwordPanel:passwordInnerForm:confirmPassword:passwordField",
 "Password123");
+        
formTester.select("content:status:resources:firstLevelContainer:first:container:content:group",
 0);
+
+        TESTER.executeAjaxEvent(
+                TAB_PANEL + 
"outerObjectsRepeater:2:outer:dialog:footer:inputs:0:submit", 
Constants.ON_CLICK);
+
+        TESTER.assertInfoMessages("Operation executed successfully");
+        TESTER.cleanupFeedbackMessages();
+    }
 }

Reply via email to