You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by md...@apache.org on 2015/08/27 13:12:52 UTC

[25/33] syncope git commit: [SYNCOPE-686] Merge from 1_2_X

http://git-wip-us.apache.org/repos/asf/syncope/blob/054ea9ca/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
----------------------------------------------------------------------
diff --cc fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
index 34a9349,0000000..78eb504
mode 100644,000000..100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
@@@ -1,354 -1,0 +1,354 @@@
 +/*
 + * 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.fit.core.reference;
 +
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertNotEquals;
 +import static org.junit.Assert.assertNotNull;
 +import static org.junit.Assert.assertNull;
 +import static org.junit.Assert.assertTrue;
 +import static org.junit.Assert.fail;
 +
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.security.AccessControlException;
 +import java.util.Map;
 +import java.util.Set;
 +import javax.ws.rs.core.Response;
 +import org.apache.commons.lang3.StringUtils;
 +import org.apache.commons.lang3.tuple.Pair;
 +import org.apache.cxf.helpers.IOUtils;
 +import org.apache.syncope.client.lib.SyncopeClient;
 +import org.apache.syncope.common.lib.SyncopeClientException;
 +import org.apache.syncope.common.lib.mod.StatusMod;
 +import org.apache.syncope.common.lib.mod.UserMod;
 +import org.apache.syncope.common.lib.to.MembershipTO;
 +import org.apache.syncope.common.lib.to.UserTO;
 +import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
 +import org.apache.syncope.common.lib.to.WorkflowFormTO;
 +import org.apache.syncope.common.lib.types.AnyTypeKind;
 +import org.apache.syncope.common.lib.types.ClientExceptionType;
 +import org.apache.syncope.common.rest.api.Preference;
 +import org.apache.syncope.common.rest.api.RESTHeaders;
 +import org.apache.syncope.common.rest.api.service.UserSelfService;
 +import org.apache.syncope.common.rest.api.service.UserService;
 +import org.junit.Assume;
 +import org.junit.FixMethodOrder;
 +import org.junit.Test;
 +import org.junit.runners.MethodSorters;
 +import org.springframework.jdbc.core.JdbcTemplate;
 +
 +@FixMethodOrder(MethodSorters.JVM)
 +public class UserSelfITCase extends AbstractITCase {
 +
 +    @Test
 +    public void selfRegistrationAllowed() {
 +        assertTrue(syncopeService.info().isSelfRegAllowed());
 +    }
 +
 +    @Test
 +    public void create() {
 +        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 +
 +        // 1. self-registration as admin: failure
 +        try {
 +            userSelfService.create(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"), true);
 +            fail();
 +        } catch (AccessControlException e) {
 +            assertNotNull(e);
 +        }
 +
 +        // 2. self-registration as anonymous: works
 +        SyncopeClient anonClient = clientFactory.createAnonymous();
 +        UserTO self = anonClient.getService(UserSelfService.class).
 +                create(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"), true).
 +                readEntity(UserTO.class);
 +        assertNotNull(self);
 +        assertEquals("createApproval", self.getStatus());
 +    }
 +
 +    @Test
 +    public void createAndApprove() {
 +        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 +
 +        // self-create user with membership: goes 'createApproval' with resources and membership but no propagation
 +        UserTO userTO = UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org");
 +        MembershipTO membership = new MembershipTO();
 +        membership.setRightKey(3L);
 +        userTO.getMemberships().add(membership);
 +        userTO.getResources().add(RESOURCE_NAME_TESTDB);
 +
 +        SyncopeClient anonClient = clientFactory.createAnonymous();
 +        userTO = anonClient.getService(UserSelfService.class).
 +                create(userTO, true).
 +                readEntity(UserTO.class);
 +        assertNotNull(userTO);
 +        assertEquals("createApproval", userTO.getStatus());
 +        assertFalse(userTO.getMemberships().isEmpty());
 +        assertFalse(userTO.getResources().isEmpty());
 +
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
 +            fail();
 +        } catch (SyncopeClientException e) {
 +            assertEquals(ClientExceptionType.NotFound, e.getType());
 +        }
 +
 +        // now approve and verify that propagation has happened
 +        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
 +        form = userWorkflowService.claimForm(form.getTaskId());
 +        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
 +        props.get("approve").setValue(Boolean.TRUE.toString());
 +        form.getProperties().clear();
 +        form.getProperties().addAll(props.values());
 +        userTO = userWorkflowService.submitForm(form);
 +        assertNotNull(userTO);
 +        assertEquals("active", userTO.getStatus());
 +        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey()));
 +    }
 +
 +    @Test
 +    public void read() {
 +        UserService userService2 = clientFactory.create("rossini", ADMIN_PWD).getService(UserService.class);
 +
 +        try {
 +            userService2.read(1L);
 +            fail();
 +        } catch (AccessControlException e) {
 +            assertNotNull(e);
 +        }
 +
 +        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create("rossini", ADMIN_PWD).self();
 +        assertEquals("rossini", self.getValue().getUsername());
 +    }
 +
 +    @Test
 +    public void updateWithoutApproval() {
 +        // 1. create user as admin
 +        UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"));
 +        assertNotNull(created);
 +        assertFalse(created.getUsername().endsWith("XX"));
 +
 +        // 2. self-update (username) - works
 +        UserMod userMod = new UserMod();
 +        userMod.setKey(created.getKey());
 +        userMod.setUsername(created.getUsername() + "XX");
 +
 +        SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
 +        UserTO updated = authClient.getService(UserSelfService.class).update(userMod).
 +                readEntity(UserTO.class);
 +        assertNotNull(updated);
 +        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
 +                ? "active" : "created", updated.getStatus());
 +        assertTrue(updated.getUsername().endsWith("XX"));
 +    }
 +
 +    @Test
 +    public void updateWithApproval() {
 +        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 +
 +        // 1. create user as admin
 +        UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"));
 +        assertNotNull(created);
 +        assertFalse(created.getUsername().endsWith("XX"));
 +
 +        // 2. self-update (username + memberships + resource) - works but needs approval
 +        UserMod userMod = new UserMod();
 +        userMod.setKey(created.getKey());
 +        userMod.setUsername(created.getUsername() + "XX");
 +        userMod.getMembershipsToAdd().add(7L);
 +        userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
 +        userMod.setPassword("newPassword123");
 +        StatusMod statusMod = new StatusMod();
 +        statusMod.setOnSyncope(false);
-         statusMod.getResourceNames().add(RESOURCE_NAME_TESTDB);
++        statusMod.getResources().add(RESOURCE_NAME_TESTDB);
 +        userMod.setPwdPropRequest(statusMod);
 +
 +        SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
 +        UserTO updated = authClient.getService(UserSelfService.class).update(userMod).
 +                readEntity(UserTO.class);
 +        assertNotNull(updated);
 +        assertEquals("updateApproval", updated.getStatus());
 +        assertFalse(updated.getUsername().endsWith("XX"));
 +        assertTrue(updated.getMemberships().isEmpty());
 +
 +        // no propagation happened
 +        assertTrue(updated.getResources().isEmpty());
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), updated.getKey());
 +            fail();
 +        } catch (SyncopeClientException e) {
 +            assertEquals(ClientExceptionType.NotFound, e.getType());
 +        }
 +
 +        // 3. approve self-update as admin
 +        WorkflowFormTO form = userWorkflowService.getFormForUser(updated.getKey());
 +        form = userWorkflowService.claimForm(form.getTaskId());
 +        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
 +        props.get("approve").setValue(Boolean.TRUE.toString());
 +        form.getProperties().clear();
 +        form.getProperties().addAll(props.values());
 +        updated = userWorkflowService.submitForm(form);
 +        assertNotNull(updated);
 +        assertEquals("active", updated.getStatus());
 +        assertTrue(updated.getUsername().endsWith("XX"));
 +        assertEquals(1, updated.getMemberships().size());
 +
 +        // check that propagation also happened
 +        assertTrue(updated.getResources().contains(RESOURCE_NAME_TESTDB));
 +        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), updated.getKey()));
 +    }
 +
 +    @Test
 +    public void delete() {
 +        UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"));
 +        assertNotNull(created);
 +
 +        SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
 +        UserTO deleted = authClient.getService(UserSelfService.class).delete().readEntity(UserTO.class);
 +        assertNotNull(deleted);
 +        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
 +                ? "deleteApproval" : null, deleted.getStatus());
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE373() {
 +        UserTO userTO = adminClient.self().getValue();
 +        assertEquals(ADMIN_UNAME, userTO.getUsername());
 +    }
 +
 +    @Test
 +    public void noContent() throws IOException {
 +        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 +
 +        SyncopeClient anonClient = clientFactory.createAnonymous();
 +        UserSelfService noContentService = anonClient.prefer(UserSelfService.class, Preference.RETURN_NO_CONTENT);
 +
 +        UserTO user = UserITCase.getUniqueSampleTO("nocontent-anonymous@syncope.apache.org");
 +
 +        Response response = noContentService.create(user, true);
 +        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
 +        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
 +        assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
 +    }
 +
 +    @Test
 +    public void passwordReset() {
 +        // 0. ensure that password request DOES require security question
 +        configurationService.set(attrTO("passwordReset.securityQuestion", "true"));
 +
 +        // 1. create an user with security question and answer
 +        UserTO user = UserITCase.getUniqueSampleTO("pwdReset@syncope.apache.org");
 +        user.setSecurityQuestion(1L);
 +        user.setSecurityAnswer("Rossi");
 +        user.getResources().add(RESOURCE_NAME_TESTDB);
 +        createUser(user);
 +
 +        // verify propagation (including password) on external db
 +        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
 +        String pwdOnResource = jdbcTemplate.queryForObject("SELECT password FROM test WHERE id=?", String.class,
 +                user.getUsername());
 +        assertTrue(StringUtils.isNotBlank(pwdOnResource));
 +
 +        // 2. verify that new user is able to authenticate
 +        SyncopeClient authClient = clientFactory.create(user.getUsername(), "password123");
 +        UserTO read = authClient.self().getValue();
 +        assertNotNull(read);
 +
 +        // 3. request password reset (as anonymous) providing the expected security answer
 +        SyncopeClient anonClient = clientFactory.createAnonymous();
 +        try {
 +            anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), "WRONG");
 +            fail();
 +        } catch (SyncopeClientException e) {
 +            assertEquals(ClientExceptionType.InvalidSecurityAnswer, e.getType());
 +        }
 +        anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), "Rossi");
 +
 +        // 4. get token (normally sent via e-mail, now reading as admin)
 +        String token = userService.read(read.getKey()).getToken();
 +        assertNotNull(token);
 +
 +        // 5. confirm password reset
 +        try {
 +            anonClient.getService(UserSelfService.class).confirmPasswordReset("WRONG TOKEN", "newPassword");
 +            fail();
 +        } catch (SyncopeClientException e) {
 +            assertEquals(ClientExceptionType.NotFound, e.getType());
 +            assertTrue(e.getMessage().contains("WRONG TOKEN"));
 +        }
 +        anonClient.getService(UserSelfService.class).confirmPasswordReset(token, "newPassword123");
 +
 +        // 6. verify that password was reset and token removed
 +        authClient = clientFactory.create(user.getUsername(), "newPassword123");
 +        read = authClient.self().getValue();
 +        assertNotNull(read);
 +        assertNull(read.getToken());
 +
 +        // 7. verify that password was changed on external resource
 +        String newPwdOnResource = jdbcTemplate.queryForObject("SELECT password FROM test WHERE id=?", String.class,
 +                user.getUsername());
 +        assertTrue(StringUtils.isNotBlank(newPwdOnResource));
 +        assertNotEquals(pwdOnResource, newPwdOnResource);
 +    }
 +
 +    @Test
 +    public void passwordResetWithoutSecurityQuestion() {
 +        // 0. disable security question for password reset
 +        configurationService.set(attrTO("passwordReset.securityQuestion", "false"));
 +
 +        // 1. create an user with security question and answer
 +        UserTO user = UserITCase.getUniqueSampleTO("pwdResetNoSecurityQuestion@syncope.apache.org");
 +        createUser(user);
 +
 +        // 2. verify that new user is able to authenticate
 +        SyncopeClient authClient = clientFactory.create(user.getUsername(), "password123");
 +        UserTO read = authClient.self().getValue();
 +        assertNotNull(read);
 +
 +        // 3. request password reset (as anonymous) with no security answer
 +        SyncopeClient anonClient = clientFactory.createAnonymous();
 +        anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), null);
 +
 +        // 4. get token (normally sent via e-mail, now reading as admin)
 +        String token = userService.read(read.getKey()).getToken();
 +        assertNotNull(token);
 +
 +        // 5. confirm password reset
 +        try {
 +            anonClient.getService(UserSelfService.class).confirmPasswordReset("WRONG TOKEN", "newPassword");
 +            fail();
 +        } catch (SyncopeClientException e) {
 +            assertEquals(ClientExceptionType.NotFound, e.getType());
 +            assertTrue(e.getMessage().contains("WRONG TOKEN"));
 +        }
 +        anonClient.getService(UserSelfService.class).confirmPasswordReset(token, "newPassword123");
 +
 +        // 6. verify that password was reset and token removed
 +        authClient = clientFactory.create(user.getUsername(), "newPassword123");
 +        read = authClient.self().getValue();
 +        assertNotNull(read);
 +        assertNull(read.getToken());
 +
 +        // 7. re-enable security question for password reset
 +        configurationService.set(attrTO("passwordReset.securityQuestion", "true"));
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/syncope/blob/054ea9ca/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
----------------------------------------------------------------------
diff --cc fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
index 5644447,0000000..cb166a9
mode 100644,000000..100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
@@@ -1,616 -1,0 +1,616 @@@
 +/*
 + * 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.fit.core.reference;
 +
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertNotNull;
 +import static org.junit.Assert.assertTrue;
 +
 +import java.util.Collections;
 +import java.util.Locale;
 +import java.util.Map;
 +import org.apache.commons.lang3.SerializationUtils;
 +import org.apache.syncope.common.lib.mod.AttrMod;
 +import org.apache.syncope.common.lib.mod.StatusMod;
 +import org.apache.syncope.common.lib.mod.UserMod;
 +import org.apache.syncope.common.lib.to.AttrTO;
 +import org.apache.syncope.common.lib.to.ConnInstanceTO;
 +import org.apache.syncope.common.lib.to.ConnObjectTO;
 +import org.apache.syncope.common.lib.to.MappingItemTO;
 +import org.apache.syncope.common.lib.to.MappingTO;
 +import org.apache.syncope.common.lib.to.MembershipTO;
 +import org.apache.syncope.common.lib.to.ResourceTO;
 +import org.apache.syncope.common.lib.to.GroupTO;
 +import org.apache.syncope.common.lib.to.ProvisionTO;
 +import org.apache.syncope.common.lib.to.UserTO;
 +import org.apache.syncope.common.lib.types.AnyTypeKind;
 +import org.apache.syncope.common.lib.types.ConnConfProperty;
 +import org.apache.syncope.common.lib.types.IntMappingType;
 +import org.apache.syncope.common.lib.types.MappingPurpose;
 +import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 +import org.apache.syncope.common.rest.api.service.ResourceService;
 +import org.identityconnectors.framework.common.objects.ObjectClass;
 +import org.junit.FixMethodOrder;
 +import org.junit.Test;
 +import org.junit.runners.MethodSorters;
 +import org.springframework.jdbc.core.JdbcTemplate;
 +
 +@FixMethodOrder(MethodSorters.JVM)
 +public class VirAttrITCase extends AbstractITCase {
 +
 +    @Test
 +    public void issueSYNCOPE16() {
 +        UserTO userTO = UserITCase.getUniqueSampleTO("issue16@apache.org");
 +
 +        MembershipTO membershipTO = new MembershipTO();
 +        membershipTO.setRightKey(8L);
 +        userTO.getMemberships().add(membershipTO);
 +
 +        // 1. create user
 +        UserTO actual = createUser(userTO);
 +        assertNotNull(actual);
 +
 +        // 2. check for virtual attribute value
 +        actual = userService.read(actual.getKey());
 +        assertNotNull(actual);
 +        assertEquals("virtualvalue", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
 +
 +        UserMod userMod = new UserMod();
 +        userMod.setKey(actual.getKey());
 +        userMod.getVirAttrsToRemove().add("virtualdata");
 +        userMod.getVirAttrsToUpdate().add(attrMod("virtualdata", "virtualupdated"));
 +
 +        // 3. update virtual attribute
 +        actual = updateUser(userMod);
 +        assertNotNull(actual);
 +
 +        // 4. check for virtual attribute value
 +        actual = userService.read(actual.getKey());
 +        assertNotNull(actual);
 +        assertEquals("virtualupdated", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE260() {
 +        // ----------------------------------
 +        // create user and check virtual attribute value propagation
 +        // ----------------------------------
 +        UserTO userTO = UserITCase.getUniqueSampleTO("260@a.com");
 +        userTO.getResources().add(RESOURCE_NAME_WS2);
 +
 +        userTO = createUser(userTO);
 +        assertNotNull(userTO);
 +        assertFalse(userTO.getPropagationStatusTOs().isEmpty());
 +        assertEquals(RESOURCE_NAME_WS2, userTO.getPropagationStatusTOs().get(0).getResource());
 +        assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
 +
 +        ConnObjectTO connObjectTO =
 +                resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
 +        assertNotNull(connObjectTO);
 +        assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
 +        // ----------------------------------
 +
 +        // ----------------------------------
 +        // update user virtual attribute and check virtual attribute value update propagation
 +        // ----------------------------------
 +        UserMod userMod = new UserMod();
 +        userMod.setKey(userTO.getKey());
 +
 +        AttrMod attrMod = new AttrMod();
 +        attrMod.setSchema("virtualdata");
 +        attrMod.getValuesToBeRemoved().add("virtualvalue");
 +        attrMod.getValuesToBeAdded().add("virtualvalue2");
 +
 +        userMod.getVirAttrsToUpdate().add(attrMod);
 +
 +        userTO = updateUser(userMod);
 +        assertNotNull(userTO);
 +        assertFalse(userTO.getPropagationStatusTOs().isEmpty());
 +        assertEquals("ws-target-resource-2", userTO.getPropagationStatusTOs().get(0).getResource());
 +        assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
 +
 +        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
 +        assertNotNull(connObjectTO);
 +        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
 +        // ----------------------------------
 +
 +        // ----------------------------------
 +        // suspend/reactivate user and check virtual attribute value (unchanged)
 +        // ----------------------------------
 +        StatusMod statusMod = new StatusMod();
 +        statusMod.setKey(userTO.getKey());
 +        statusMod.setType(StatusMod.ModType.SUSPEND);
 +        userTO = userService.status(statusMod).readEntity(UserTO.class);
 +        assertEquals("suspended", userTO.getStatus());
 +
 +        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
 +        assertNotNull(connObjectTO);
 +        assertFalse(connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
 +        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
 +
 +        statusMod = new StatusMod();
 +        statusMod.setKey(userTO.getKey());
 +        statusMod.setType(StatusMod.ModType.REACTIVATE);
 +        userTO = userService.status(statusMod).readEntity(UserTO.class);
 +        assertEquals("active", userTO.getStatus());
 +
 +        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
 +        assertNotNull(connObjectTO);
 +        assertFalse(connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
 +        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
 +        // ----------------------------------
 +
 +        // ----------------------------------
 +        // update user attribute and check virtual attribute value (unchanged)
 +        // ----------------------------------
 +        userMod = new UserMod();
 +        userMod.setKey(userTO.getKey());
 +
 +        attrMod = new AttrMod();
 +        attrMod.setSchema("surname");
 +        attrMod.getValuesToBeRemoved().add("Surname");
 +        attrMod.getValuesToBeAdded().add("Surname2");
 +
 +        userMod.getPlainAttrsToUpdate().add(attrMod);
 +
 +        userTO = updateUser(userMod);
 +        assertNotNull(userTO);
 +        assertFalse(userTO.getPropagationStatusTOs().isEmpty());
 +        assertEquals(RESOURCE_NAME_WS2, userTO.getPropagationStatusTOs().get(0).getResource());
 +        assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
 +
 +        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
 +        assertNotNull(connObjectTO);
 +        assertEquals("Surname2", connObjectTO.getPlainAttrMap().get("SURNAME").getValues().get(0));
 +
 +        // attribute "name" mapped on virtual attribute "virtualdata" shouldn't be changed
 +        assertFalse(connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
 +        assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
 +        // ----------------------------------
 +
 +        // ----------------------------------
 +        // remove user virtual attribute and check virtual attribute value (reset)
 +        // ----------------------------------
 +        userMod = new UserMod();
 +        userMod.setKey(userTO.getKey());
 +        userMod.getVirAttrsToRemove().add("virtualdata");
 +
 +        userTO = updateUser(userMod);
 +        assertNotNull(userTO);
 +        assertTrue(userTO.getVirAttrs().isEmpty());
 +        assertFalse(userTO.getPropagationStatusTOs().isEmpty());
 +        assertEquals(RESOURCE_NAME_WS2, userTO.getPropagationStatusTOs().get(0).getResource());
 +        assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
 +
 +        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
 +        assertNotNull(connObjectTO);
 +
 +        // attribute "name" mapped on virtual attribute "virtualdata" should be reset
 +        assertTrue(connObjectTO.getPlainAttrMap().get("NAME").getValues() == null
 +                || connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
 +        // ----------------------------------
 +    }
 +
 +    @Test
 +    public void virAttrCache() {
 +        UserTO userTO = UserITCase.getUniqueSampleTO("virattrcache@apache.org");
 +        userTO.getVirAttrs().clear();
 +
 +        AttrTO virAttrTO = new AttrTO();
 +        virAttrTO.setSchema("virtualdata");
 +        virAttrTO.getValues().add("virattrcache");
 +        userTO.getVirAttrs().add(virAttrTO);
 +
 +        userTO.getMemberships().clear();
 +        userTO.getResources().clear();
 +        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
 +
 +        // 1. create user
 +        UserTO actual = createUser(userTO);
 +        assertNotNull(actual);
 +
 +        // 2. check for virtual attribute value
 +        actual = userService.read(actual.getKey());
 +        assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
 +
 +        // 3. update virtual attribute directly
 +        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
 +
 +        String value = jdbcTemplate.queryForObject(
 +                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
 +        assertEquals("virattrcache", value);
 +
 +        jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", actual.getKey());
 +
 +        value = jdbcTemplate.queryForObject(
 +                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
 +        assertEquals("virattrcache2", value);
 +
 +        // 4. check for cached attribute value
 +        actual = userService.read(actual.getKey());
 +        assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
 +
 +        UserMod userMod = new UserMod();
 +        userMod.setKey(actual.getKey());
 +
 +        AttrMod virtualdata = new AttrMod();
 +        virtualdata.setSchema("virtualdata");
 +        virtualdata.getValuesToBeAdded().add("virtualupdated");
 +
 +        userMod.getVirAttrsToRemove().add("virtualdata");
 +        userMod.getVirAttrsToUpdate().add(virtualdata);
 +
 +        // 5. update virtual attribute
 +        actual = updateUser(userMod);
 +        assertNotNull(actual);
 +
 +        // 6. check for virtual attribute value
 +        actual = userService.read(actual.getKey());
 +        assertNotNull(actual);
 +        assertEquals("virtualupdated", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE397() {
 +        ResourceTO csv = resourceService.read(RESOURCE_NAME_CSV);
 +        MappingTO origMapping = SerializationUtils.clone(csv.getProvisions().get(0).getMapping());
 +        try {
 +            // change mapping of resource-csv
 +            assertNotNull(origMapping);
 +            for (MappingItemTO item : csv.getProvisions().get(0).getMapping().getItems()) {
 +                if ("email".equals(item.getIntAttrName())) {
 +                    // unset internal attribute mail and set virtual attribute virtualdata as mapped to external email
 +                    item.setIntMappingType(IntMappingType.UserVirtualSchema);
 +                    item.setIntAttrName("virtualdata");
 +                    item.setPurpose(MappingPurpose.BOTH);
 +                    item.setExtAttrName("email");
 +                }
 +            }
 +
 +            resourceService.update(csv);
 +            csv = resourceService.read(RESOURCE_NAME_CSV);
 +            assertNotNull(csv.getProvisions().get(0).getMapping());
 +
 +            boolean found = false;
 +            for (MappingItemTO item : csv.getProvisions().get(0).getMapping().getItems()) {
 +                if ("email".equals(item.getExtAttrName()) && "virtualdata".equals(item.getIntAttrName())) {
 +                    found = true;
 +                }
 +            }
 +
 +            assertTrue(found);
 +
 +            // create a new user
 +            UserTO userTO = UserITCase.getUniqueSampleTO("syncope397@syncope.apache.org");
 +            userTO.getAuxClasses().add("csv");
 +            userTO.getResources().clear();
 +            userTO.getMemberships().clear();
 +            userTO.getDerAttrs().clear();
 +            userTO.getVirAttrs().clear();
 +
 +            userTO.getDerAttrs().add(attrTO("csvuserid", null));
 +            userTO.getDerAttrs().add(attrTO("cn", null));
 +            userTO.getVirAttrs().add(attrTO("virtualdata", "test@testone.org"));
 +            // assign resource-csv to user
 +            userTO.getResources().add(RESOURCE_NAME_CSV);
 +            // save user
 +            UserTO created = createUser(userTO);
 +            // make std controls about user
 +            assertNotNull(created);
 +            assertTrue(RESOURCE_NAME_CSV.equals(created.getResources().iterator().next()));
 +            // update user
 +            UserTO toBeUpdated = userService.read(created.getKey());
 +            UserMod userMod = new UserMod();
 +            userMod.setKey(toBeUpdated.getKey());
 +            userMod.setPassword("password234");
 +            // assign new resource to user
 +            userMod.getResourcesToAdd().add(RESOURCE_NAME_WS2);
 +            //modify virtual attribute
 +            userMod.getVirAttrsToRemove().add("virtualdata");
 +            userMod.getVirAttrsToUpdate().add(attrMod("virtualdata", "test@testoneone.com"));
 +
 +            // check Syncope change password
 +            StatusMod pwdPropRequest = new StatusMod();
 +            pwdPropRequest.setOnSyncope(true);
-             pwdPropRequest.getResourceNames().add(RESOURCE_NAME_WS2);
++            pwdPropRequest.getResources().add(RESOURCE_NAME_WS2);
 +            userMod.setPwdPropRequest(pwdPropRequest);
 +
 +            toBeUpdated = updateUser(userMod);
 +            assertNotNull(toBeUpdated);
 +            assertEquals("test@testoneone.com", toBeUpdated.getVirAttrs().iterator().next().getValues().get(0));
 +            // check if propagates correctly with assertEquals on size of tasks list
 +            assertEquals(2, toBeUpdated.getPropagationStatusTOs().size());
 +        } finally {
 +            // restore mapping of resource-csv
 +            csv.getProvisions().get(0).setMapping(origMapping);
 +            resourceService.update(csv);
 +        }
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE442() {
 +        UserTO userTO = UserITCase.getUniqueSampleTO("syncope442@apache.org");
 +        userTO.getVirAttrs().clear();
 +
 +        AttrTO virAttrTO = new AttrTO();
 +        virAttrTO.setSchema("virtualdata");
 +        virAttrTO.getValues().add("virattrcache");
 +        userTO.getVirAttrs().add(virAttrTO);
 +
 +        userTO.getMemberships().clear();
 +        userTO.getResources().clear();
 +        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
 +
 +        // 1. create user
 +        UserTO actual = createUser(userTO);
 +        assertNotNull(actual);
 +
 +        // 2. check for virtual attribute value
 +        actual = userService.read(actual.getKey());
 +        assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
 +
 +        // ----------------------------------------
 +        // 3. force cache expiring without any modification
 +        // ----------------------------------------
 +        String jdbcURL = null;
 +        ConnInstanceTO connInstanceTO = connectorService.readByResource(
 +                RESOURCE_NAME_DBVIRATTR, Locale.ENGLISH.getLanguage());
 +        for (ConnConfProperty prop : connInstanceTO.getConfiguration()) {
 +            if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
 +                jdbcURL = prop.getValues().iterator().next().toString();
 +                prop.getValues().clear();
 +                prop.getValues().add("jdbc:h2:tcp://localhost:9092/xxx");
 +            }
 +        }
 +
 +        connectorService.update(connInstanceTO);
 +
 +        UserMod userMod = new UserMod();
 +        userMod.setKey(actual.getKey());
 +
 +        AttrMod virtualdata = new AttrMod();
 +        virtualdata.setSchema("virtualdata");
 +        virtualdata.getValuesToBeAdded().add("virtualupdated");
 +
 +        userMod.getVirAttrsToRemove().add("virtualdata");
 +        userMod.getVirAttrsToUpdate().add(virtualdata);
 +
 +        actual = updateUser(userMod);
 +        assertNotNull(actual);
 +        // ----------------------------------------
 +
 +        // ----------------------------------------
 +        // 4. update virtual attribute
 +        // ----------------------------------------
 +        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
 +
 +        String value = jdbcTemplate.queryForObject(
 +                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
 +        assertEquals("virattrcache", value);
 +
 +        jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", actual.getKey());
 +
 +        value = jdbcTemplate.queryForObject(
 +                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
 +        assertEquals("virattrcache2", value);
 +        // ----------------------------------------
 +
 +        actual = userService.read(actual.getKey());
 +        assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
 +
 +        // ----------------------------------------
 +        // 5. restore connector
 +        // ----------------------------------------
 +        for (ConnConfProperty prop : connInstanceTO.getConfiguration()) {
 +            if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
 +                prop.getValues().clear();
 +                prop.getValues().add(jdbcURL);
 +            }
 +        }
 +
 +        connectorService.update(connInstanceTO);
 +        // ----------------------------------------
 +
 +        actual = userService.read(actual.getKey());
 +        assertEquals("virattrcache2", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE436() {
 +        UserTO userTO = UserITCase.getUniqueSampleTO("syncope436@syncope.apache.org");
 +        userTO.getMemberships().clear();
 +        userTO.getResources().clear();
 +        userTO.getResources().add(RESOURCE_NAME_LDAP);
 +        userTO.getVirAttrs().add(attrTO("virtualReadOnly", "readOnly"));
 +        userTO = createUser(userTO);
 +        //Finding no values because the virtual attribute is readonly 
 +        assertTrue(userTO.getVirAttrMap().get("virtualReadOnly").getValues().isEmpty());
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE453() {
 +        final String resourceName = "issueSYNCOPE453-Res-" + getUUIDString();
 +        final String groupName = "issueSYNCOPE453-Group-" + getUUIDString();
 +
 +        // -------------------------------------------
 +        // Create a resource ad-hoc
 +        // -------------------------------------------
 +        ResourceTO resourceTO = new ResourceTO();
 +
 +        resourceTO.setKey(resourceName);
 +        resourceTO.setConnector(107L);
 +
 +        ProvisionTO provisionTO = new ProvisionTO();
 +        provisionTO.setAnyType(AnyTypeKind.USER.name());
 +        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
 +        resourceTO.getProvisions().add(provisionTO);
 +
 +        MappingTO mapping = new MappingTO();
 +        provisionTO.setMapping(mapping);
 +
 +        MappingItemTO item = new MappingItemTO();
 +        item.setIntAttrName("aLong");
 +        item.setIntMappingType(IntMappingType.UserPlainSchema);
 +        item.setExtAttrName("ID");
 +        item.setPurpose(MappingPurpose.PROPAGATION);
 +        item.setConnObjectKey(true);
 +        mapping.setConnObjectKeyItem(item);
 +
 +        item = new MappingItemTO();
 +        item.setExtAttrName("USERNAME");
 +        item.setIntAttrName("username");
 +        item.setIntMappingType(IntMappingType.Username);
 +        item.setPurpose(MappingPurpose.PROPAGATION);
 +        mapping.getItems().add(item);
 +
 +        item = new MappingItemTO();
 +        item.setExtAttrName("EMAIL");
 +        item.setIntAttrName("rvirtualdata");
 +        item.setIntMappingType(IntMappingType.GroupVirtualSchema);
 +        item.setPurpose(MappingPurpose.PROPAGATION);
 +        mapping.getItems().add(item);
 +
 +        assertNotNull(getObject(
 +                resourceService.create(resourceTO).getLocation(), ResourceService.class, ResourceTO.class));
 +        // -------------------------------------------
 +
 +        // -------------------------------------------
 +        // Create a VirAttrITCase ad-hoc
 +        // -------------------------------------------
 +        GroupTO groupTO = new GroupTO();
 +        groupTO.setName(groupName);
 +        groupTO.setRealm("/");
 +        groupTO.getVirAttrs().add(attrTO("rvirtualdata", "ml@group.it"));
 +        groupTO.getResources().add(RESOURCE_NAME_LDAP);
 +        groupTO = createGroup(groupTO);
 +        assertEquals(1, groupTO.getVirAttrs().size());
 +        assertEquals("ml@group.it", groupTO.getVirAttrs().iterator().next().getValues().get(0));
 +        // -------------------------------------------
 +
 +        // -------------------------------------------
 +        // Create new user
 +        // -------------------------------------------
 +        UserTO userTO = UserITCase.getUniqueSampleTO("syncope453@syncope.apache.org");
 +        userTO.getPlainAttrs().add(attrTO("aLong", "123"));
 +        userTO.getResources().clear();
 +        userTO.getResources().add(resourceName);
 +        userTO.getVirAttrs().clear();
 +        userTO.getDerAttrs().clear();
 +        userTO.getMemberships().clear();
 +
 +        MembershipTO membership = new MembershipTO();
 +        membership.setRightKey(groupTO.getKey());
 +        userTO.getMemberships().add(membership);
 +
 +        userTO = createUser(userTO);
 +        assertEquals(2, userTO.getPropagationStatusTOs().size());
 +        assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
 +        assertTrue(userTO.getPropagationStatusTOs().get(1).getStatus().isSuccessful());
 +
 +        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
 +
 +        final Map<String, Object> actuals = jdbcTemplate.queryForMap(
 +                "SELECT id, surname, email FROM testsync WHERE id=?",
 +                new Object[] { Integer.parseInt(userTO.getPlainAttrMap().get("aLong").getValues().get(0)) });
 +
 +        assertEquals(userTO.getPlainAttrMap().get("aLong").getValues().get(0), actuals.get("id").toString());
 +        assertEquals("ml@group.it", actuals.get("email"));
 +        // -------------------------------------------
 +
 +        // -------------------------------------------
 +        // Delete resource and group ad-hoc
 +        // -------------------------------------------
 +        resourceService.delete(resourceName);
 +        groupService.delete(groupTO.getKey());
 +        // -------------------------------------------
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE459() {
 +        UserTO userTO = UserITCase.getUniqueSampleTO("syncope459@apache.org");
 +        userTO.getResources().clear();
 +        userTO.getMemberships().clear();
 +        userTO.getVirAttrs().clear();
 +
 +        AttrTO virtualReadOnly = attrTO("virtualReadOnly", "");
 +        virtualReadOnly.getValues().clear();
 +
 +        userTO.getVirAttrs().add(virtualReadOnly);
 +
 +        userTO = createUser(userTO);
 +
 +        assertNotNull(userTO.getVirAttrMap().get("virtualReadOnly"));
 +
 +        UserMod userMod = new UserMod();
 +        userMod.setKey(userTO.getKey());
 +
 +        AttrMod virtualdata = new AttrMod();
 +        virtualdata.setSchema("virtualdata");
 +
 +        userMod.getVirAttrsToUpdate().add(virtualdata);
 +
 +        userTO = updateUser(userMod);
 +        assertNotNull(userTO.getVirAttrMap().get("virtualdata"));
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE501() {
 +        // 1. create user and propagate him on resource-db-virattr
 +        UserTO userTO = UserITCase.getUniqueSampleTO("syncope501@apache.org");
 +        userTO.getResources().clear();
 +        userTO.getMemberships().clear();
 +        userTO.getVirAttrs().clear();
 +
 +        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
 +
 +        // virtualdata is mapped with username
 +        final AttrTO virtualData = attrTO("virtualdata", "syncope501@apache.org");
 +        userTO.getVirAttrs().add(virtualData);
 +
 +        userTO = createUser(userTO);
 +
 +        assertNotNull(userTO.getVirAttrMap().get("virtualdata"));
 +        assertEquals("syncope501@apache.org", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
 +
 +        // 2. update virtual attribute
 +        UserMod userMod = new UserMod();
 +        userMod.setKey(userTO.getKey());
 +
 +        final StatusMod statusMod = new StatusMod();
-         statusMod.getResourceNames().addAll(Collections.<String>emptySet());
++        statusMod.getResources().addAll(Collections.<String>emptySet());
 +        statusMod.setOnSyncope(false);
 +
 +        userMod.setPwdPropRequest(statusMod);
 +        // change virtual attribute value
 +        final AttrMod virtualDataMod = new AttrMod();
 +        virtualDataMod.setSchema("virtualdata");
 +        virtualDataMod.getValuesToBeAdded().add("syncope501_updated@apache.org");
 +        virtualDataMod.getValuesToBeRemoved().add("syncope501@apache.org");
 +        userMod.getVirAttrsToUpdate().add(virtualDataMod);
 +        userMod.getVirAttrsToRemove().add("virtualdata");
 +
 +        userTO = updateUser(userMod);
 +        assertNotNull(userTO);
 +
 +        // 3. check that user virtual attribute has really been updated 
 +        assertFalse(userTO.getVirAttrMap().get("virtualdata").getValues().isEmpty());
 +        assertEquals("syncope501_updated@apache.org", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
 +    }
 +}