You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2020/02/26 16:42:59 UTC

[syncope] branch master updated (f640386 -> 43b05de)

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git.


    from f640386  [SYNCOPE-1531] More robust handling in case value for key column is missing
     new 34aa2dc  [SYNCOPE-1537] Password and username of LinkedAccounts now saved properly from Admin Console
     new 503bbb4  [SYNCOPE-1537] Ensure proper password management for Linked Accounts
     new 2ac89d9  [SYNCOPE-1544] Also removed readonly attributes from showing in the list of plain attributes for linkedaccounts
     new 43b05de  [SYNCOPE-1537] Linked account update using put

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../wizards/any/LinkedAccountCredentialsPanel.java | 65 ++++++++++-----
 .../wizards/any/LinkedAccountPlainAttrsPanel.java  | 48 ++++++-----
 .../wizards/any/LinkedAccountWizardBuilder.java    | 10 +--
 .../apache/syncope/common/lib/AnyOperations.java   |  1 -
 .../provisioning/java/data/UserDataBinderImpl.java | 29 ++++---
 .../org/apache/syncope/fit/AbstractITCase.java     | 12 ++-
 .../syncope/fit/core/LinkedAccountITCase.java      | 96 ++++++++++++++++++++++
 7 files changed, 201 insertions(+), 60 deletions(-)


[syncope] 04/04: [SYNCOPE-1537] Linked account update using put

Posted by il...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit 43b05dea91097162c95e99184bab4bb724c6bb7f
Author: dima.ayash <di...@tirasa.net>
AuthorDate: Wed Feb 26 16:27:59 2020 +0100

    [SYNCOPE-1537] Linked account update using put
---
 .../wizards/any/LinkedAccountCredentialsPanel.java |  2 +-
 .../wizards/any/LinkedAccountPlainAttrsPanel.java  |  1 -
 .../apache/syncope/common/lib/AnyOperations.java   |  1 -
 .../org/apache/syncope/fit/AbstractITCase.java     | 12 ++-
 .../syncope/fit/core/LinkedAccountITCase.java      | 96 ++++++++++++++++++++++
 5 files changed, 108 insertions(+), 4 deletions(-)

diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
index 0540407..e30cfc4 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
@@ -28,6 +28,7 @@ import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponent
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPasswordFieldPanel;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel;
+import org.apache.syncope.client.ui.commons.wizards.any.EntityWrapper;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.ComponentTag;
@@ -143,5 +144,4 @@ public class LinkedAccountCredentialsPanel extends WizardStep {
             }
         };
     }
-
 }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
index edfdfe7..aa2024b 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
@@ -47,7 +47,6 @@ import org.apache.syncope.client.console.layout.AnyLayoutUtils;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
-import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.CheckBox;
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
index 08364ae..b5becbf 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
@@ -330,7 +330,6 @@ public final class AnyOperations {
                 EntityTOUtils.buildLinkedAccountMap(original.getLinkedAccounts());
 
         updatedAccounts.entrySet().stream().
-                filter(entry -> (!originalAccounts.containsKey(entry.getKey()))).
                 forEachOrdered(entry -> {
                     result.getLinkedAccounts().add(new LinkedAccountUR.Builder().
                             operation(PatchOperation.ADD_REPLACE).
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
index 111690f..38ca003 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.fit;
 
+import static de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType.java;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.fail;
@@ -53,6 +54,7 @@ import org.apache.syncope.common.keymaster.client.api.DomainOps;
 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
 import org.apache.syncope.common.keymaster.client.self.SelfKeymasterClientContext;
 import org.apache.syncope.common.keymaster.client.zookeper.ZookeeperKeymasterClientContext;
+import org.apache.syncope.common.lib.AnyOperations;
 import org.apache.syncope.common.lib.request.AnyObjectUR;
 import org.apache.syncope.common.lib.request.AttrPatch;
 import org.apache.syncope.common.lib.request.GroupUR;
@@ -484,6 +486,13 @@ public abstract class AbstractITCase {
                 });
     }
 
+    protected ProvisioningResult<UserTO> updateUser(final UserTO userTO) {
+        UserTO before = userService.read(userTO.getKey());
+        return userService.update(AnyOperations.diff(userTO, before, false)).
+                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+                });
+    }
+
     protected ProvisioningResult<UserTO> deleteUser(final String key) {
         return userService.delete(key).
                 readEntity(new GenericType<ProvisioningResult<UserTO>>() {
@@ -616,7 +625,8 @@ public abstract class AbstractITCase {
             ctx = getLdapResourceDirContext(bindDn, bindPwd);
 
             List<ModificationItem> items = new ArrayList<>();
-            attributes.forEach((key, value) -> items.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute(key, value))));
+            attributes.forEach((key, value) -> items.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
+                    new BasicAttribute(key, value))));
 
             ctx.modifyAttributes(objectDn, items.toArray(new ModificationItem[] {}));
         } catch (Exception e) {
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LinkedAccountITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LinkedAccountITCase.java
index c187fc2..54f8325 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LinkedAccountITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LinkedAccountITCase.java
@@ -152,6 +152,46 @@ public class LinkedAccountITCase extends AbstractITCase {
     }
 
     @Test
+    public void createWithLinkedAccountThenUpdateUsingPutThenRemove() throws NamingException {
+        // 1. create user with linked account
+        UserCR userCR = UserITCase.getSample(
+                "linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
+        String connObjectKeyValue = "uid=" + userCR.getUsername() + ",ou=People,o=isp";
+        String privilege = applicationService.read("mightyApp").getPrivileges().get(0).getKey();
+
+        LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_LDAP, connObjectKeyValue).build();
+        account.setUsername("LinkedUsername");
+        account.getPlainAttrs().add(attr("surname", "LINKED_SURNAME"));
+        account.getPrivileges().add(privilege);
+        userCR.getLinkedAccounts().add(account);
+
+        UserTO user = createUser(userCR).getEntity();
+        assertNotNull(user.getKey());
+        assertEquals(1, user.getLinkedAccounts().size());
+        assertEquals(privilege, user.getLinkedAccounts().get(0).getPrivileges().iterator().next());
+        assertEquals("LinkedUsername", user.getLinkedAccounts().get(0).getUsername());
+        assertEquals("LINKED_SURNAME", account.getPlainAttr("surname").get().getValues().get(0));
+
+        // 2. update linked account
+        account.getPlainAttrs().clear();
+        account.setUsername("LinkedUsernameUpdated");
+        account.getPlainAttrs().add(attr("email", "UPDATED_EMAIL@syncope.apache.org"));
+        account.getPlainAttrs().add(attr("surname", "UPDATED_SURNAME"));
+        user.getLinkedAccounts().clear();
+        user.getLinkedAccounts().add(account);
+
+        user = updateUser(user).getEntity();
+        assertEquals(1, user.getLinkedAccounts().size());
+        assertEquals("LinkedUsernameUpdated", user.getLinkedAccounts().get(0).getUsername());
+        assertEquals("UPDATED_SURNAME", account.getPlainAttr("surname").get().getValues().get(0));
+
+        // 3. remove linked account from user
+        user.getLinkedAccounts().clear();
+        user = updateUser(user).getEntity();
+        assertTrue(user.getLinkedAccounts().isEmpty());
+    }
+
+    @Test
     public void createWithoutLinkedAccountThenAdd() throws NamingException {
         // 1. create user without linked account
         UserCR userCR = UserITCase.getSample(
@@ -198,6 +238,62 @@ public class LinkedAccountITCase extends AbstractITCase {
     }
 
     @Test
+    public void createWithoutLinkedAccountThenAddAndUpdatePassword() throws NamingException {
+        // 1. set the return value parameter to true
+        confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "return.password.value", true);
+
+        // 2. create user without linked account
+        UserCR userCR = UserITCase.getSample(
+                "linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
+        String connObjectKeyValue = "uid=" + userCR.getUsername() + ",ou=People,o=isp";
+
+        UserTO user = createUser(userCR).getEntity();
+        assertNotNull(user.getKey());
+        assertTrue(user.getLinkedAccounts().isEmpty());
+
+        // 3. add linked account to user without password
+        UserUR userUR = new UserUR();
+        userUR.setKey(user.getKey());
+
+        LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_LDAP, connObjectKeyValue).build();
+        userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
+
+        user = updateUser(userUR).getEntity();
+        assertEquals(1, user.getLinkedAccounts().size());
+        assertNull(user.getLinkedAccounts().get(0).getPassword());
+
+        // 4. update linked account with adding a password
+        account.setPassword("Password123");
+        userUR = new UserUR();
+        userUR.setKey(user.getKey());
+        userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
+        user = updateUser(userUR).getEntity();
+        assertNotNull(user.getLinkedAccounts().get(0).getPassword());
+
+        // 5. update linked account  password
+        String beforeUpdatePassword = user.getLinkedAccounts().get(0).getPassword();
+        account.setPassword("Password123Updated");
+        userUR = new UserUR();
+        userUR.setKey(user.getKey());
+
+        userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
+        user = updateUser(userUR).getEntity();
+        assertNotNull(user.getLinkedAccounts().get(0).getPassword());
+        assertNotEquals(beforeUpdatePassword, user.getLinkedAccounts().get(0).getPassword());
+
+        // 6. set linked account password to null
+        account.setPassword(null);
+        userUR = new UserUR();
+        userUR.setKey(user.getKey());
+
+        userUR.getLinkedAccounts().add(new LinkedAccountUR.Builder().linkedAccountTO(account).build());
+        user = updateUser(userUR).getEntity();
+        assertNull(user.getLinkedAccounts().get(0).getPassword());
+
+        confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "return.password.value", false);
+    }
+
+    @Test
     public void push() {
         // 0a. read configured cipher algorithm in order to be able to restore it at the end of test
         String origpwdCipherAlgo = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,


[syncope] 03/04: [SYNCOPE-1544] Also removed readonly attributes from showing in the list of plain attributes for linkedaccounts

Posted by il...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit 2ac89d97b64026ac656bd84e63e287c1812b7afc
Author: skylark17 <sk...@apache.org>
AuthorDate: Wed Feb 26 12:33:26 2020 +0100

    [SYNCOPE-1544] Also removed readonly attributes from showing in the list of plain attributes for linkedaccounts
---
 .../wizards/any/LinkedAccountCredentialsPanel.java | 15 ++++++-
 .../wizards/any/LinkedAccountPlainAttrsPanel.java  | 47 +++++++++++++---------
 2 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
index 967b839..0540407 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
@@ -42,6 +42,10 @@ public class LinkedAccountCredentialsPanel extends WizardStep {
 
     private static final long serialVersionUID = 5116461957402341603L;
 
+    private String usernameValue;
+
+    private String passwordValue;
+
     private final LinkedAccountTO linkedAccountTO;
 
     public LinkedAccountCredentialsPanel(final EntityWrapper<LinkedAccountTO> modelObject) {
@@ -68,7 +72,6 @@ public class LinkedAccountCredentialsPanel extends WizardStep {
                 new PropertyModel<>(linkedAccountTO, "password"),
                 false);
         passwordField.setMarkupId("password");
-        passwordField.setPlaceholder("password");
         passwordField.setRequired(true);
         FieldPanel.class.cast(passwordField).setReadOnly(StringUtils.isBlank(linkedAccountTO.getPassword()));
         LinkedAccountPlainAttrProperty passwordProperty = new LinkedAccountPlainAttrProperty();
@@ -102,10 +105,18 @@ public class LinkedAccountCredentialsPanel extends WizardStep {
                     @Override
                     protected void onUpdate(final AjaxRequestTarget target) {
                         FieldPanel.class.cast(panel).setReadOnly(!model.getObject());
-                        if (!model.getObject()) {
+                        if (model.getObject()) {
+                            if (property.getSchema().equals("password")) {
+                                linkedAccountTO.setPassword(passwordValue);
+                            } else if (property.getSchema().equals("username")) {
+                                linkedAccountTO.setUsername(usernameValue);
+                            }
+                        } else {
                             if (property.getSchema().equals("password")) {
+                                passwordValue = linkedAccountTO.getPassword();
                                 linkedAccountTO.setPassword(null);
                             } else if (property.getSchema().equals("username")) {
+                                usernameValue = linkedAccountTO.getUsername();
                                 linkedAccountTO.setUsername(null);
                             }
                         }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
index 3346de8..edfdfe7 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
@@ -23,7 +23,6 @@ import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.boot
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -78,15 +77,17 @@ public class LinkedAccountPlainAttrsPanel extends AbstractAttrsWizardStep<PlainS
 
         super(userTO,
                 AjaxWizard.Mode.EDIT,
-                new AnyTypeRestClient().read(userTO.getType()).getClasses(),
+                AnyTypeRestClient.read(userTO.getType()).getClasses(),
                 AnyLayoutUtils.fetch(List.of(userTO.getType())).getUser().getWhichPlainAttrs(),
                 modelObject);
 
         this.linkedAccountTO = modelObject.getInnerObject();
-        this.fixedAttrs.addAll(this.linkedAccountTO.getPlainAttrs());
+        this.fixedAttrs.addAll(this.linkedAccountTO.getPlainAttrs().stream().
+                filter(attrTO -> checkIsReadonlyAttr(attrTO.getSchema())).
+                collect(Collectors.toList()));
         this.userTO = userTO;
 
-        add(new Accordion("plainSchemas", Collections.<ITab>singletonList(new AbstractTab(
+        add(new Accordion("plainSchemas", List.of(new AbstractTab(
                 new ResourceModel("attributes.accordion", "Plain Attributes")) {
 
             private static final long serialVersionUID = -7078941093668723016L;
@@ -166,11 +167,12 @@ public class LinkedAccountPlainAttrsPanel extends AbstractAttrsWizardStep<PlainS
     }
 
     private void updateAccountPlainSchemas(final LinkedAccountPlainAttrProperty property, final Boolean modelObject) {
-        Set<Attr> withoutCurrentSChema = new HashSet<>(linkedAccountTO.getPlainAttrs().stream().
-                filter(attr -> !attr.getSchema().equals(property.getSchema())).
+        Set<Attr> withoutCurrentSchema = new HashSet<>(linkedAccountTO.getPlainAttrs().stream().
+                filter(attrTO -> !attrTO.getSchema().equals(property.getSchema())
+                && checkIsReadonlyAttr(attrTO.getSchema())).
                 collect(Collectors.toSet()));
         linkedAccountTO.getPlainAttrs().clear();
-        linkedAccountTO.getPlainAttrs().addAll(withoutCurrentSChema);
+        linkedAccountTO.getPlainAttrs().addAll(withoutCurrentSchema);
         if (modelObject) {
             linkedAccountTO.getPlainAttrs().add(
                     fixedAttrs.stream().filter(attrTO -> attrTO.getSchema().equals(property.getSchema())).findFirst().
@@ -187,19 +189,24 @@ public class LinkedAccountPlainAttrsPanel extends AbstractAttrsWizardStep<PlainS
     @Override
     protected void setAttrs() {
         List<Attr> attrs = new ArrayList<>();
-        setFixedAttr(schemas.values());
+        List<PlainSchemaTO> notReadonlyValues = schemas.values().stream().
+                filter(schema -> checkIsReadonlyAttr(schema.getKey())).
+                collect(Collectors.toList());
+        setFixedAttr(notReadonlyValues);
         Map<String, Attr> attrMap = EntityTOUtils.buildAttrMap(fixedAttrs);
 
-        attrs.addAll(schemas.values().stream().map(schema -> {
-            Attr attrTO = new Attr();
-            attrTO.setSchema(schema.getKey());
-            if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) {
-                attrTO.getValues().add("");
-            } else {
-                attrTO = attrMap.get(schema.getKey());
-            }
-            return attrTO;
-        }).collect(Collectors.toList()));
+        attrs.addAll(notReadonlyValues.stream().
+                map(schema -> {
+                    Attr attrTO = new Attr();
+                    attrTO.setSchema(schema.getKey());
+                    if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) {
+                        attrTO.getValues().add("");
+                    } else {
+                        attrTO = attrMap.get(schema.getKey());
+                    }
+                    return attrTO;
+                }).
+                collect(Collectors.toList()));
 
         fixedAttrs.clear();
         fixedAttrs.addAll(attrs);
@@ -220,6 +227,10 @@ public class LinkedAccountPlainAttrsPanel extends AbstractAttrsWizardStep<PlainS
         });
     }
 
+    private boolean checkIsReadonlyAttr(final String schema) {
+        return schemas.isEmpty() ? true : !schemas.get(schema).isReadonly();
+    }
+
     private class PlainSchemasOwn extends PlainSchemas<List<Attr>> {
 
         private static final long serialVersionUID = -4730563859116024676L;


[syncope] 01/04: [SYNCOPE-1537] Password and username of LinkedAccounts now saved properly from Admin Console

Posted by il...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit 34aa2dcdb36886df09e9e5c2cc3792486d0d4050
Author: skylark17 <sk...@apache.org>
AuthorDate: Tue Feb 25 12:50:36 2020 +0100

    [SYNCOPE-1537] Password and username of LinkedAccounts now saved properly from Admin Console
---
 .../wizards/any/LinkedAccountCredentialsPanel.java | 52 +++++++++++++---------
 .../wizards/any/LinkedAccountWizardBuilder.java    | 10 ++---
 2 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
index 237504f..967b839 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountCredentialsPanel.java
@@ -42,39 +42,42 @@ public class LinkedAccountCredentialsPanel extends WizardStep {
 
     private static final long serialVersionUID = 5116461957402341603L;
 
-    public LinkedAccountCredentialsPanel(final LinkedAccountTO linkedAccountTO) {
+    private final LinkedAccountTO linkedAccountTO;
+
+    public LinkedAccountCredentialsPanel(final EntityWrapper<LinkedAccountTO> modelObject) {
         super();
         setOutputMarkupId(true);
 
+        linkedAccountTO = modelObject.getInnerObject();
+
         AjaxTextFieldPanel usernameField = new AjaxTextFieldPanel(
                 "username",
                 "username",
-                new PropertyModel<>(linkedAccountTO, "username"),
-                false);
-        usernameField.setOutputMarkupId(true);
+                new PropertyModel<>(linkedAccountTO, "username"));
         FieldPanel.class.cast(usernameField).setReadOnly(StringUtils.isBlank(linkedAccountTO.getUsername()));
-        LinkedAccountPlainAttrProperty property = new LinkedAccountPlainAttrProperty();
-        property.setOverridable(StringUtils.isNotBlank(linkedAccountTO.getUsername()));
-        property.setSchema("username");
-        property.getValues().add(linkedAccountTO.getUsername());
-        usernameField.showExternAction(checkboxToggle(property, usernameField));
-        add(usernameField);
+        LinkedAccountPlainAttrProperty usernameProperty = new LinkedAccountPlainAttrProperty();
+        usernameProperty.setOverridable(StringUtils.isNotBlank(linkedAccountTO.getUsername()));
+        usernameProperty.setSchema("username");
+        usernameProperty.getValues().add(linkedAccountTO.getUsername());
+        usernameField.showExternAction(checkboxToggle(usernameProperty, usernameField));
+        add(usernameField.setOutputMarkupId(true));
 
         AjaxPasswordFieldPanel passwordField = new AjaxPasswordFieldPanel(
                 "password",
                 "password",
-                new PropertyModel<>(linkedAccountTO, "password"));
-        passwordField.setOutputMarkupId(true);
-        passwordField.setRequired(true);
+                new PropertyModel<>(linkedAccountTO, "password"),
+                false);
         passwordField.setMarkupId("password");
+        passwordField.setPlaceholder("password");
+        passwordField.setRequired(true);
         FieldPanel.class.cast(passwordField).setReadOnly(StringUtils.isBlank(linkedAccountTO.getPassword()));
-        property = new LinkedAccountPlainAttrProperty();
-        property.setOverridable(StringUtils.isNotBlank(linkedAccountTO.getPassword()));
-        property.setSchema("password");
-        property.getValues().add(linkedAccountTO.getPassword());
-        passwordField.showExternAction(checkboxToggle(property, passwordField));
-        ((PasswordTextField) passwordField.getField()).setResetPassword(true);
-        add(passwordField);
+        LinkedAccountPlainAttrProperty passwordProperty = new LinkedAccountPlainAttrProperty();
+        passwordProperty.setOverridable(StringUtils.isNotBlank(linkedAccountTO.getPassword()));
+        passwordProperty.setSchema("password");
+        passwordProperty.getValues().add(linkedAccountTO.getPassword());
+        passwordField.showExternAction(checkboxToggle(passwordProperty, passwordField));
+        ((PasswordTextField) passwordField.getField()).setResetPassword(false);
+        add(passwordField.setOutputMarkupId(true));
     }
 
     private FormComponent<?> checkboxToggle(
@@ -98,7 +101,14 @@ public class LinkedAccountCredentialsPanel extends WizardStep {
 
                     @Override
                     protected void onUpdate(final AjaxRequestTarget target) {
-                        panel.setReadOnly(!model.getObject());
+                        FieldPanel.class.cast(panel).setReadOnly(!model.getObject());
+                        if (!model.getObject()) {
+                            if (property.getSchema().equals("password")) {
+                                linkedAccountTO.setPassword(null);
+                            } else if (property.getSchema().equals("username")) {
+                                linkedAccountTO.setUsername(null);
+                            }
+                        }
                         target.add(panel);
                     }
                 });
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
index e9115b8..fcfcb9e 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountWizardBuilder.java
@@ -61,7 +61,7 @@ public class LinkedAccountWizardBuilder extends BaseAjaxWizardBuilder<LinkedAcco
     @Override
     protected WizardModel buildModelSteps(final LinkedAccountTO modelObject, final WizardModel wizardModel) {
         wizardModel.add(new LinkedAccountDetailsPanel(modelObject));
-        wizardModel.add(new LinkedAccountCredentialsPanel(modelObject));
+        wizardModel.add(new LinkedAccountCredentialsPanel(new EntityWrapper<>(modelObject)));
         wizardModel.add(new LinkedAccountPlainAttrsPanel(new EntityWrapper<>(modelObject), model.getObject()));
         wizardModel.add(new LinkedAccountPrivilegesPanel(modelObject));
         return wizardModel;
@@ -73,10 +73,10 @@ public class LinkedAccountWizardBuilder extends BaseAjaxWizardBuilder<LinkedAcco
 
         LinkedAccountUR linkedAccountPatch = new LinkedAccountUR.Builder().linkedAccountTO(modelObject).build();
         linkedAccountPatch.setLinkedAccountTO(modelObject);
-        UserUR patch = new UserUR();
-        patch.setKey(model.getObject().getKey());
-        patch.getLinkedAccounts().add(linkedAccountPatch);
-        model.setObject(userRestClient.update(model.getObject().getETagValue(), patch).getEntity());
+        UserUR req = new UserUR();
+        req.setKey(model.getObject().getKey());
+        req.getLinkedAccounts().add(linkedAccountPatch);
+        model.setObject(userRestClient.update(model.getObject().getETagValue(), req).getEntity());
 
         return modelObject;
     }


[syncope] 02/04: [SYNCOPE-1537] Ensure proper password management for Linked Accounts

Posted by il...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit 503bbb4b619f353c68dba71b1a107ddca82aba18
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Tue Feb 25 12:58:55 2020 +0100

    [SYNCOPE-1537] Ensure proper password management for Linked Accounts
---
 .../provisioning/java/data/UserDataBinderImpl.java | 29 +++++++++++++---------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index cd3f9aa..45cbd65 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -182,7 +182,9 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
                     }.get();
 
             account.setUsername(accountTO.getUsername());
-            if (StringUtils.isNotBlank(accountTO.getPassword())) {
+            if (StringUtils.isBlank(accountTO.getPassword())) {
+                account.setEncodedPassword(null, null);
+            } else if (!accountTO.getPassword().equals(account.getPassword())) {
                 account.setPassword(accountTO.getPassword(), CipherAlgorithm.AES);
             }
             account.setSuspended(accountTO.isSuspended());
@@ -367,13 +369,18 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         setRealm(user, userUR);
 
         // password
-        if (userUR.getPassword() != null && StringUtils.isNotBlank(userUR.getPassword().getValue())) {
-            if (userUR.getPassword().isOnSyncope()) {
-                setPassword(user, userUR.getPassword().getValue(), scce);
-                user.setChangePwdDate(new Date());
-            }
+        if (userUR.getPassword() != null) {
+            if (userUR.getPassword().getOperation() == PatchOperation.DELETE) {
+                user.setEncodedPassword(null, null);
+                propByRes.addAll(ResourceOperation.UPDATE, userUR.getPassword().getResources());
+            } else if (StringUtils.isNotBlank(userUR.getPassword().getValue())) {
+                if (userUR.getPassword().isOnSyncope()) {
+                    setPassword(user, userUR.getPassword().getValue(), scce);
+                    user.setChangePwdDate(new Date());
+                }
 
-            propByRes.addAll(ResourceOperation.UPDATE, userUR.getPassword().getResources());
+                propByRes.addAll(ResourceOperation.UPDATE, userUR.getPassword().getResources());
+            }
         }
 
         // username
@@ -618,11 +625,9 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
                         invalidValues);
             }
         });
-        user.getLinkedAccounts().forEach(account -> {
-            propByLinkedAccount.add(
-                    ResourceOperation.CREATE,
-                    Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue()));
-        });
+        user.getLinkedAccounts().forEach(account -> propByLinkedAccount.add(
+                ResourceOperation.CREATE,
+                Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
 
         // finalize resource management
         reasons.entrySet().stream().