[SYNCOPE-1102] Minimum Viable Fix
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/53dfa408 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/53dfa408 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/53dfa408 Branch: refs/heads/1_1_X Commit: 53dfa40883653a4bc621f5586a98c23efe9ea761 Parents: a4d4929 Author: Francesco Chicchiriccò <ilgro...@apache.org> Authored: Tue Jun 6 12:58:15 2017 +0200 Committer: Francesco Chicchiriccò <ilgro...@apache.org> Committed: Tue Jun 6 12:58:15 2017 +0200 ---------------------------------------------------------------------- .../persistence/beans/membership/MAttr.java | 2 +- .../core/persistence/beans/role/RAttr.java | 2 +- .../core/persistence/beans/user/UAttr.java | 2 +- .../persistence/dao/impl/AttrValueDAOImpl.java | 7 ++++++- .../data/AbstractAttributableDataBinder.java | 4 +++- .../syncope/core/rest/UserTestITCase.java | 21 ++++++++++++++++++++ 6 files changed, 33 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/53dfa408/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java b/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java index 4ebb7f6..204259e 100644 --- a/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java +++ b/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java @@ -143,7 +143,7 @@ public class MAttr extends AbstractAttr { @Override public <T extends AbstractAttrValue> void setUniqueValue(final T uniqueAttributeValue) { - if (!(uniqueAttributeValue instanceof MAttrUniqueValue)) { + if (uniqueAttributeValue != null && !(uniqueAttributeValue instanceof MAttrUniqueValue)) { throw new ClassCastException("uniqueAttributeValue is expected to be typed MAttrUniqueValue: " + uniqueAttributeValue.getClass().getName()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/53dfa408/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java b/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java index 48d9cd3..e4bf76e 100644 --- a/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java +++ b/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java @@ -140,7 +140,7 @@ public class RAttr extends AbstractAttr { @Override public <T extends AbstractAttrValue> void setUniqueValue(final T uniqueAttributeValue) { - if (!(uniqueAttributeValue instanceof RAttrUniqueValue)) { + if (uniqueAttributeValue != null && !(uniqueAttributeValue instanceof RAttrUniqueValue)) { throw new ClassCastException("uniqueAttributeValue is expected to be typed RAttrUniqueValue: " + uniqueAttributeValue.getClass().getName()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/53dfa408/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java b/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java index 7642ba9..b4183ef 100644 --- a/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java +++ b/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java @@ -161,7 +161,7 @@ public class UAttr extends AbstractAttr { @Override public <T extends AbstractAttrValue> void setUniqueValue(final T uniqueAttributeValue) { - if (!(uniqueAttributeValue instanceof UAttrUniqueValue)) { + if (uniqueAttributeValue != null && !(uniqueAttributeValue instanceof UAttrUniqueValue)) { throw new ClassCastException("uniqueAttributeValue is expected to be typed UAttrUniqueValue: " + uniqueAttributeValue.getClass().getName()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/53dfa408/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttrValueDAOImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttrValueDAOImpl.java b/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttrValueDAOImpl.java index 4ce43a1..0cf58f4 100644 --- a/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttrValueDAOImpl.java +++ b/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttrValueDAOImpl.java @@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.dao.impl; import java.util.List; import javax.persistence.TypedQuery; +import org.apache.syncope.core.persistence.beans.AbstractAttrUniqueValue; import org.apache.syncope.core.persistence.beans.AbstractAttrValue; import org.apache.syncope.core.persistence.dao.AttrValueDAO; import org.springframework.stereotype.Repository; @@ -56,7 +57,11 @@ public class AttrValueDAOImpl extends AbstractDAOImpl implements AttrValueDAO { @Override public <T extends AbstractAttrValue> void delete(final T attributeValue) { if (attributeValue.getAttribute() != null) { - attributeValue.getAttribute().removeValue(attributeValue); + if (attributeValue instanceof AbstractAttrUniqueValue) { + attributeValue.getAttribute().setUniqueValue(null); + } else { + attributeValue.getAttribute().removeValue(attributeValue); + } } entityManager.remove(attributeValue); http://git-wip-us.apache.org/repos/asf/syncope/blob/53dfa408/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java b/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java index f6ed113..6d1e45a 100644 --- a/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java +++ b/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java @@ -464,8 +464,10 @@ public abstract class AbstractAttributableDataBinder { } } } + Class<AbstractAttrValue> valueClass = + schema.isUniqueConstraint() ? attrUtil.attrUniqueValueClass() : attrUtil.attrValueClass(); for (Long attributeValueId : valuesToBeRemoved) { - attributeValueDAO.delete(attributeValueId, attrUtil.attrValueClass()); + attributeValueDAO.delete(attributeValueId, valueClass); } // 1.2 add values http://git-wip-us.apache.org/repos/asf/syncope/blob/53dfa408/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java b/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java index 7619fa4..933ea8e 100644 --- a/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java +++ b/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java @@ -2144,4 +2144,25 @@ public class UserTestITCase extends AbstractTest { } return newMaxId; } + + @Test + public void issueSYNCOPE1102() { + UserTO userTO = getUniqueSampleTO("a...@gmail.com"); + userTO = createUser(userTO); + assertNotNull(userTO.getId()); + + UserMod userMod = new UserMod(); + userMod.setId(userTO.getId()); + + AttributeMod userIdMod = new AttributeMod(); + userIdMod.setSchema("userId"); + userIdMod.getValuesToBeAdded().add("b" + userTO.getUsername()); + userIdMod.getValuesToBeRemoved().add(userTO.getUsername()); + userMod.getAttributesToBeUpdated().add(userIdMod); + + userTO = userService.update(userMod.getId(), userMod); + assertEquals("b" + userTO.getUsername(), userTO.getAttributeMap().get("userId").getValues().get(0)); + + userService.delete(100L); + } }