Repository: syncope Updated Branches: refs/heads/2_0_X c42936baa -> 64fa513e1
[SYNCOPE-620] Merging SYNCOPE-632 Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/64fa513e Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/64fa513e Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/64fa513e Branch: refs/heads/2_0_X Commit: 64fa513e11e28f8f24ddacf803e6036edaf78895 Parents: c42936b Author: Francesco Chicchiriccò <[email protected]> Authored: Thu Jan 29 17:50:57 2015 +0100 Committer: Francesco Chicchiriccò <[email protected]> Committed: Thu Jan 29 17:50:57 2015 +0100 ---------------------------------------------------------------------- .../apache/syncope/common/lib/to/MappingTO.java | 17 ++-- .../fit/server/reference/AbstractITCase.java | 27 ++++-- .../fit/server/reference/ConnectorITCase.java | 14 ++- .../fit/server/reference/RoleITCase.java | 92 ++++++++++++++++++++ .../fit/server/reference/UserSelfITCase.java | 2 +- syncope620/pom.xml | 4 +- .../syncope/server/logic/ResourceLogic.java | 4 +- .../data/AbstractAttributableDataBinder.java | 27 +++++- .../java/data/RoleDataBinderImpl.java | 21 +++-- .../java/data/UserDataBinderImpl.java | 28 +++--- 10 files changed, 187 insertions(+), 49 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java ---------------------------------------------------------------------- diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java index 3d29914..aea9556 100644 --- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java +++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java @@ -46,18 +46,17 @@ public class MappingTO extends AbstractBaseBean { this.accountLink = accountLink; } - @SuppressWarnings("unchecked") - public <T extends MappingItemTO> T getAccountIdItem() { - T accountIdItem = null; + public MappingItemTO getAccountIdItem() { + MappingItemTO accountIdItem = null; for (MappingItemTO item : getItems()) { if (item.isAccountid()) { - accountIdItem = (T) item; + accountIdItem = item; } } return accountIdItem; } - protected <T extends MappingItemTO> boolean addAccountIdItem(final T accountIdItem) { + protected boolean addAccountIdItem(final MappingItemTO accountIdItem) { if (IntMappingType.UserVirtualSchema == accountIdItem.getIntMappingType() || IntMappingType.RoleVirtualSchema == accountIdItem.getIntMappingType() || IntMappingType.MembershipVirtualSchema == accountIdItem.getIntMappingType() @@ -76,11 +75,9 @@ public class MappingTO extends AbstractBaseBean { } public boolean setAccountIdItem(final MappingItemTO accountIdItem) { - if (accountIdItem == null) { - return this.removeItem(getAccountIdItem()); - } else { - return addAccountIdItem(accountIdItem); - } + return accountIdItem == null + ? removeItem(getAccountIdItem()) + : addAccountIdItem(accountIdItem); } public MappingItemTO getPasswordItem() { http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java ---------------------------------------------------------------------- diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java index 255666c..e1e5769 100644 --- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java +++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java @@ -27,6 +27,7 @@ import java.util.Map; import java.util.Properties; import java.util.UUID; import javax.naming.Context; +import javax.naming.NamingException; import javax.naming.directory.InitialDirContext; import javax.sql.DataSource; import javax.ws.rs.core.Response; @@ -339,12 +340,9 @@ public abstract class AbstractITCase { return getObject(response.getLocation(), ResourceService.class, ResourceTO.class); } - protected Object getLdapRemoteObject(final String objectDn) { - return getLdapRemoteObject(null, null, objectDn); - } - @SuppressWarnings({ "unchecked", "rawtypes", "UseOfObsoleteCollectionType" }) - protected Object getLdapRemoteObject(final String bindDn, final String bindPwd, final String objectDn) { + protected InitialDirContext getLdapResourceDirContext(final String bindDn, final String bindPwd) + throws NamingException { ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP); final Map<String, ConnConfProperty> ldapConnConf = connectorService.read(ldapRes.getConnectorId()).getConfigurationMap(); @@ -359,11 +357,28 @@ public abstract class AbstractITCase { env.put(Context.SECURITY_CREDENTIALS, bindPwd == null ? ldapConnConf.get("credentials").getValues().get(0) : bindPwd); + return new InitialDirContext(env); + } + + protected Object getLdapRemoteObject(final String bindDn, final String bindPwd, final String objectDn) { + InitialDirContext ctx = null; try { - final InitialDirContext ctx = new InitialDirContext(env); + ctx = getLdapResourceDirContext(bindDn, bindPwd); return ctx.lookup(objectDn); } catch (Exception e) { return null; + } finally { + if (ctx != null) { + try { + ctx.close(); + } catch (NamingException e) { + // ignore + } + } } } + + protected Object getLdapRemoteObject(final String objectDn) { + return getLdapRemoteObject(null, null, objectDn); + } } http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java ---------------------------------------------------------------------- diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java index f426526..83e0832 100644 --- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java +++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java @@ -285,7 +285,6 @@ public class ConnectorITCase extends AbstractITCase { // ---------------------------------- // Retrieve a connector instance template. ConnInstanceTO connInstanceTO = connectorService.read(103L); - assertNotNull(connInstanceTO); // check for resource @@ -313,7 +312,7 @@ public class ConnectorITCase extends AbstractITCase { connInstanceTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class); assertNotNull(connInstanceTO); - assertTrue(connInstanceTO.getCapabilities().isEmpty()); + assertFalse(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE)); long connId = connInstanceTO.getKey(); @@ -337,26 +336,23 @@ public class ConnectorITCase extends AbstractITCase { // Check for spring bean. // ---------------------------------- ConnInstanceTO connInstanceBean = connectorService.readByResource(resourceTO.getKey()); - assertNotNull(connInstanceBean); - assertTrue(connInstanceBean.getCapabilities().isEmpty()); + assertFalse(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE)); // ---------------------------------- // ---------------------------------- // Check for spring bean update after connector instance update. // ---------------------------------- - connInstanceTO.getCapabilities().add(ConnectorCapability.SEARCH); + connInstanceTO.getCapabilities().add(ConnectorCapability.AUTHENTICATE); connectorService.update(connInstanceTO.getKey(), connInstanceTO); ConnInstanceTO actual = connectorService.read(connInstanceTO.getKey()); - assertNotNull(actual); - assertFalse(connInstanceTO.getCapabilities().isEmpty()); + assertTrue(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE)); // check for spring bean update connInstanceBean = connectorService.readByResource(resourceTO.getKey()); - - assertFalse(connInstanceBean.getCapabilities().isEmpty()); + assertTrue(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE)); // ---------------------------------- } http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java ---------------------------------------------------------------------- diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java index dbd9532..18646f5 100644 --- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java +++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java @@ -29,6 +29,11 @@ import java.io.IOException; import java.io.InputStream; import java.security.AccessControlException; import java.util.List; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; import javax.ws.rs.core.Response; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; @@ -38,12 +43,16 @@ import org.apache.syncope.common.lib.mod.ReferenceMod; import org.apache.syncope.common.lib.mod.RoleMod; import org.apache.syncope.common.lib.to.BulkActionResult; import org.apache.syncope.common.lib.to.ConnObjectTO; +import org.apache.syncope.common.lib.to.MappingItemTO; import org.apache.syncope.common.lib.to.PagedResult; import org.apache.syncope.common.lib.to.PlainSchemaTO; +import org.apache.syncope.common.lib.to.ResourceTO; import org.apache.syncope.common.lib.to.RoleTO; import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.AttributableType; import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.IntMappingType; +import org.apache.syncope.common.lib.types.MappingPurpose; import org.apache.syncope.common.lib.types.ResourceAssociationActionType; import org.apache.syncope.common.lib.types.ResourceDeassociationActionType; import org.apache.syncope.common.lib.types.SchemaType; @@ -794,4 +803,87 @@ public class RoleITCase extends AbstractITCase { assertNotNull(child.getPlainAttrMap().get("icon").getValues()); assertEquals("parentIcon", child.getPlainAttrMap().get("icon").getValues().get(0)); } + + @Test + public void issueSYNCOPE632() { + RoleTO roleTO = null; + try { + // 1. create new LDAP resource having account id mapped to a derived attribute + ResourceTO newLDAP = resourceService.read(RESOURCE_NAME_LDAP); + newLDAP.setKey("new-ldap"); + newLDAP.setPropagationPrimary(true); + MappingItemTO accountId = newLDAP.getRmapping().getAccountIdItem(); + accountId.setIntMappingType(IntMappingType.RoleDerivedSchema); + accountId.setIntAttrName("displayProperty"); + newLDAP.getRmapping().setAccountIdItem(accountId); + newLDAP.getRmapping().setAccountLink("'cn=' + displayProperty + ',ou=groups,o=isp'"); + + MappingItemTO description = new MappingItemTO(); + description.setIntMappingType(IntMappingType.RoleId); + description.setExtAttrName("description"); + description.setPurpose(MappingPurpose.BOTH); + newLDAP.getRmapping().addItem(description); + + newLDAP = createResource(newLDAP); + assertNotNull(newLDAP); + + // 2. create a role and give the resource created above + roleTO = buildRoleTO("lastRole"); + roleTO.getRAttrTemplates().add("icon"); + roleTO.getPlainAttrs().add(attrTO("icon", "anIcon")); + roleTO.getRAttrTemplates().add("show"); + roleTO.getPlainAttrs().add(attrTO("show", "true")); + roleTO.getRDerAttrTemplates().add("displayProperty"); + roleTO.getDerAttrs().add(attrTO("displayProperty", null)); + roleTO.getResources().clear(); + roleTO.getResources().add("new-ldap"); + + roleTO = createRole(roleTO); + assertNotNull(roleTO); + + // 3. update the role + RoleMod roleMod = new RoleMod(); + roleMod.setKey(roleTO.getKey()); + roleMod.getPlainAttrsToRemove().add("icon"); + roleMod.getPlainAttrsToUpdate().add(attrMod("icon", "anotherIcon")); + + roleTO = updateRole(roleMod); + assertNotNull(roleTO); + + // 4. check that a single group exists in LDAP for the role created and updated above + int entries = 0; + DirContext ctx = null; + try { + ctx = getLdapResourceDirContext(null, null); + + SearchControls ctls = new SearchControls(); + ctls.setReturningAttributes(new String[] { "*", "+" }); + ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + NamingEnumeration<SearchResult> result = + ctx.search("ou=groups,o=isp", "(description=" + roleTO.getKey() + ")", ctls); + while (result.hasMore()) { + result.next(); + entries++; + } + } catch (Exception e) { + // ignore + } finally { + if (ctx != null) { + try { + ctx.close(); + } catch (NamingException e) { + // ignore + } + } + } + + assertEquals(1, entries); + } finally { + if (roleTO != null) { + roleService.delete(roleTO.getKey()); + } + resourceService.delete("new-ldap"); + } + } } http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java ---------------------------------------------------------------------- diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java index 1847422..665e482 100644 --- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java +++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java @@ -159,7 +159,7 @@ public class UserSelfITCase extends AbstractITCase { } @Test - public void updateWitApproval() { + public void updateWithApproval() { Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)); // 1. create user as admin http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/pom.xml ---------------------------------------------------------------------- diff --git a/syncope620/pom.xml b/syncope620/pom.xml index 7abfd74..d911dd8 100644 --- a/syncope620/pom.xml +++ b/syncope620/pom.xml @@ -594,7 +594,7 @@ under the License. <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> - <version>1.8.4</version> + <version>1.8.5</version> </dependency> <dependency> @@ -940,7 +940,7 @@ under the License. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> - <version>2.9</version> + <version>2.10</version> <configuration> <outputDirectory>${bundles.directory}</outputDirectory> <artifactItems> http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java ---------------------------------------------------------------------- diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java index 18c1f58..d5827b6 100644 --- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java +++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java @@ -179,8 +179,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> { MappingItem accountIdItem = attrUtil.getAccountIdItem(resource); if (accountIdItem == null) { - throw new NotFoundException("AccountId mapping for " + type + " " + id + " on resource '" + resourceName - + "'"); + throw new NotFoundException( + "AccountId mapping for " + type + " " + id + " on resource '" + resourceName + "'"); } final String accountIdValue = MappingUtil.getAccountIdValue( subject, resource, attrUtil.getAccountIdItem(resource)); http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java ---------------------------------------------------------------------- diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java index f7e75c0..d81e6ab 100644 --- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java +++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java @@ -20,9 +20,11 @@ package org.apache.syncope.server.provisioning.java.data; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.SyncopeClientCompositeException; @@ -86,6 +88,7 @@ import org.apache.syncope.common.lib.types.PropagationByResource; import org.apache.syncope.server.provisioning.java.VirAttrHandler; import org.apache.syncope.server.misc.MappingUtil; import org.apache.syncope.server.misc.jexl.JexlUtil; +import org.apache.syncope.server.persistence.api.dao.NotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -215,7 +218,7 @@ abstract class AbstractAttributableDataBinder { } private boolean evaluateMandatoryCondition(final AttributableUtil attrUtil, final ExternalResource resource, - final Attributable<?,?,?> attributable, final String intAttrName, final IntMappingType intMappingType) { + final Attributable<?, ?, ?> attributable, final String intAttrName, final IntMappingType intMappingType) { boolean result = false; @@ -751,4 +754,26 @@ abstract class AbstractAttributableDataBinder { } } } + + protected Map<String, String> getAccountIds(final Subject<?, ?, ?> subject, final AttributableType type) { + Map<String, String> accountIds = new HashMap<>(); + + for (ExternalResource resource : subject.getResources()) { + if ((type == AttributableType.USER && resource.getUmapping() != null) + || (type == AttributableType.ROLE && resource.getRmapping() != null)) { + + MappingItem accountIdItem = + attrUtilFactory.getInstance(type).getAccountIdItem(resource); + if (accountIdItem == null) { + throw new NotFoundException( + "AccountId mapping for " + type + " " + subject.getKey() + + " on resource '" + resource.getKey() + "'"); + } + + accountIds.put(resource.getKey(), MappingUtil.getAccountIdValue(subject, resource, accountIdItem)); + } + } + + return accountIds; + } } http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java index 851799c..3004a99 100644 --- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java +++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java @@ -20,7 +20,7 @@ package org.apache.syncope.server.provisioning.java.data; import java.util.ArrayList; import java.util.List; -import java.util.Set; +import java.util.Map; import org.apache.syncope.common.lib.SyncopeClientCompositeException; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.mod.RoleMod; @@ -198,7 +198,8 @@ public class RoleDataBinderImpl extends AbstractAttributableDataBinder implement SyncopeClientCompositeException scce = SyncopeClientException.buildComposite(); - Set<String> currentResources = role.getResourceNames(); + // fetch account ids before update + Map<String, String> oldAccountIds = getAccountIds(role, AttributableType.ROLE); // name SyncopeClientException invalidRoles = SyncopeClientException.build(ClientExceptionType.InvalidRoles); @@ -207,10 +208,7 @@ public class RoleDataBinderImpl extends AbstractAttributableDataBinder implement role.getParent() == null ? null : role.getParent().getKey()); if (otherRole == null || role.equals(otherRole)) { if (!roleMod.getName().equals(role.getName())) { - propByRes.addAll(ResourceOperation.UPDATE, currentResources); - for (String resource : currentResources) { - propByRes.addOldAccountId(resource, role.getName()); - } + propByRes.addAll(ResourceOperation.UPDATE, role.getResourceNames()); role.setName(roleMod.getName()); } @@ -307,6 +305,17 @@ public class RoleDataBinderImpl extends AbstractAttributableDataBinder implement // attributes, derived attributes, virtual attributes and resources propByRes.merge(fill(role, roleMod, attrUtilFactory.getInstance(AttributableType.ROLE), scce)); + // check if some account id was changed by the update above + Map<String, String> newAccountIds = getAccountIds(role, AttributableType.ROLE); + for (Map.Entry<String, String> entry : oldAccountIds.entrySet()) { + if (newAccountIds.containsKey(entry.getKey()) + && !entry.getValue().equals(newAccountIds.get(entry.getKey()))) { + + propByRes.addOldAccountId(entry.getKey(), entry.getValue()); + propByRes.add(ResourceOperation.UPDATE, entry.getKey()); + } + } + return propByRes; } http://git-wip-us.apache.org/repos/asf/syncope/blob/64fa513e/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/UserDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/UserDataBinderImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/UserDataBinderImpl.java index 4fdb0b8..5a9448d 100644 --- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/UserDataBinderImpl.java +++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/UserDataBinderImpl.java @@ -21,6 +21,7 @@ package org.apache.syncope.server.provisioning.java.data; import java.util.Collections; import java.util.Date; import java.util.HashSet; +import java.util.Map; import java.util.Set; import javax.annotation.Resource; import org.apache.commons.lang3.StringUtils; @@ -33,13 +34,11 @@ import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.AttributableType; import org.apache.syncope.common.lib.types.CipherAlgorithm; import org.apache.syncope.common.lib.types.ClientExceptionType; -import org.apache.syncope.common.lib.types.IntMappingType; import org.apache.syncope.common.lib.types.ResourceOperation; import org.apache.syncope.server.persistence.api.dao.ConfDAO; import org.apache.syncope.server.persistence.api.dao.SecurityQuestionDAO; import org.apache.syncope.server.persistence.api.entity.DerAttr; import org.apache.syncope.server.persistence.api.entity.ExternalResource; -import org.apache.syncope.server.persistence.api.entity.MappingItem; import org.apache.syncope.server.persistence.api.entity.PlainAttr; import org.apache.syncope.server.persistence.api.entity.VirAttr; import org.apache.syncope.server.persistence.api.entity.membership.MDerAttr; @@ -210,6 +209,9 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement Set<String> currentResources = user.getResourceNames(); + // fetch account ids before update + Map<String, String> oldAccountIds = getAccountIds(user, AttributableType.USER); + // password if (StringUtils.isNotBlank(userMod.getPassword())) { setPassword(user, userMod.getPassword(), scce); @@ -219,18 +221,9 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement // username if (userMod.getUsername() != null && !userMod.getUsername().equals(user.getUsername())) { - String oldUsername = user.getUsername(); - - user.setUsername(userMod.getUsername()); propByRes.addAll(ResourceOperation.UPDATE, currentResources); - for (ExternalResource resource : user.getResources()) { - for (MappingItem mapItem : resource.getUmapping().getItems()) { - if (mapItem.isAccountid() && mapItem.getIntMappingType() == IntMappingType.Username) { - propByRes.addOldAccountId(resource.getKey(), oldUsername); - } - } - } + user.setUsername(userMod.getUsername()); } // security question / answer: @@ -348,6 +341,17 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement propByRes.addAll(ResourceOperation.UPDATE, currentResources); } + // check if some account id was changed by the update above + Map<String, String> newAccountIds = getAccountIds(user, AttributableType.USER); + for (Map.Entry<String, String> entry : oldAccountIds.entrySet()) { + if (newAccountIds.containsKey(entry.getKey()) + && !entry.getValue().equals(newAccountIds.get(entry.getKey()))) { + + propByRes.addOldAccountId(entry.getKey(), entry.getValue()); + propByRes.add(ResourceOperation.UPDATE, entry.getKey()); + } + } + return propByRes; }
