/*
 * 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;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeFalse;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.naming.NamingException;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.cxf.helpers.IOUtils;
import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.common.lib.Attr;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
import org.apache.syncope.common.lib.request.AttrPatch;
import org.apache.syncope.common.lib.request.GroupCR;
import org.apache.syncope.common.lib.request.MembershipUR;
import org.apache.syncope.common.lib.request.PasswordPatch;
import org.apache.syncope.common.lib.request.StringPatchItem;
import org.apache.syncope.common.lib.request.StringReplacePatchItem;
import org.apache.syncope.common.lib.request.UserCR;
import org.apache.syncope.common.lib.request.UserUR;
import org.apache.syncope.common.lib.to.ConnObjectTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.to.ImplementationTO;
import org.apache.syncope.common.lib.to.ItemTO;
import org.apache.syncope.common.lib.to.MappingTO;
import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.ExecStatus;
import org.apache.syncope.common.lib.types.IdMImplementationType;
import org.apache.syncope.common.lib.types.IdRepoImplementationType;
import org.apache.syncope.common.lib.types.ImplementationEngine;
import org.apache.syncope.common.lib.types.MappingPurpose;
import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.beans.RealmQuery;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
import org.apache.syncope.core.spring.security.Encryptor;
import org.apache.syncope.fit.AbstractITCase;
import org.apache.syncope.fit.ElasticsearchDetector;
import org.identityconnectors.framework.common.objects.Name;
import org.identityconnectors.framework.common.objects.OperationalAttributes;
import org.junit.jupiter.api.Test;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

public class UserIssuesITCase extends AbstractITCase {

    @Test
    public void issue186() {
        // 1. create an user with strict mandatory attributes only
        UserCR userCR = new UserCR();
        userCR.setRealm(SyncopeConstants.ROOT_REALM);
        String userId = getUUIDString() + "issue186@syncope.apache.org";
        userCR.setUsername(userId);
        userCR.setPassword("password123");

        userCR.getPlainAttrs().add(attr("userId", userId));
        userCR.getPlainAttrs().add(attr("fullname", userId));
        userCR.getPlainAttrs().add(attr("surname", userId));

        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);
        assertTrue(userTO.getResources().isEmpty());

        // 2. update assigning a resource forcing mandatory constraints: must fail with RequiredValuesMissing
        UserUR userUR = new UserUR.Builder(userTO.getKey()).
                password(new PasswordPatch.Builder().value("newPassword123").build()).
                resource(new StringPatchItem.Builder().
                        operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build()).
                build();

        try {
            userTO = updateUser(userUR).getEntity();
            fail("This should not happen");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
        }

        // 3. update assigning a resource NOT forcing mandatory constraints
        // AND priority: must fail with PropagationException
        userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());

        ProvisioningResult<UserTO> result = updateUser(userUR);
        assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
        userTO = result.getEntity();

        // 4. update assigning a resource NOT forcing mandatory constraints
        // BUT not priority: must succeed
        userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(new PasswordPatch.Builder().value("newPassword123456").build());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_CSV).build());

        updateUser(userUR);
    }

    @Test
    public void issue213() {
        UserCR userCR = UserITCase.getUniqueSample("issue213@syncope.apache.org");
        userCR.getResources().add(RESOURCE_NAME_TESTDB);

        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);
        assertEquals(1, userTO.getResources().size());

        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
        String username = queryForObject(
                jdbcTemplate, MAX_WAIT_SECONDS, "SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
        assertEquals(userTO.getUsername(), username);

        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.getResources().add(
                new StringPatchItem.Builder().operation(PatchOperation.DELETE).value(RESOURCE_NAME_TESTDB).build());

        userTO = updateUser(userUR).getEntity();
        assertTrue(userTO.getResources().isEmpty());

        Exception exception = null;
        try {
            jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
        } catch (EmptyResultDataAccessException e) {
            exception = e;
        }
        assertNotNull(exception);
    }

    @Test
    public void issue234() {
        UserCR inUserTO = UserITCase.getUniqueSample("issue234@syncope.apache.org");
        inUserTO.getResources().add(RESOURCE_NAME_LDAP);

        UserTO userTO = createUser(inUserTO).getEntity();
        assertNotNull(userTO);

        UserUR userUR = new UserUR();

        userUR.setKey(userTO.getKey());
        userUR.setUsername(new StringReplacePatchItem.Builder().value('1' + userTO.getUsername()).build());

        userTO = updateUser(userUR).getEntity();
        assertNotNull(userTO);
        assertEquals('1' + inUserTO.getUsername(), userTO.getUsername());
    }

    @Test
    public void issue280() {
        UserCR userCR = UserITCase.getUniqueSample("issue280@syncope.apache.org");
        userCR.getResources().clear();
        userCR.getMemberships().clear();

        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).
                resource(RESOURCE_NAME_TESTDB).value("123password").build());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());

        ProvisioningResult<UserTO> result = updateUser(userUR);
        assertNotNull(result);

        List<PropagationStatus> propagations = result.getPropagationStatuses();
        assertNotNull(propagations);
        assertEquals(1, propagations.size());

        assertEquals(ExecStatus.SUCCESS, propagations.get(0).getStatus());

        String resource = propagations.get(0).getResource();
        assertEquals(RESOURCE_NAME_TESTDB, resource);
    }

    @Test
    public void issue281() {
        UserCR userCR = UserITCase.getUniqueSample("issue281@syncope.apache.org");
        userCR.getResources().clear();
        userCR.getMemberships().clear();
        userCR.getResources().add(RESOURCE_NAME_CSV);

        ProvisioningResult<UserTO> result = createUser(userCR);
        assertNotNull(result);

        List<PropagationStatus> propagations = result.getPropagationStatuses();
        assertNotNull(propagations);
        assertEquals(1, propagations.size());
        assertNotEquals(ExecStatus.SUCCESS, propagations.get(0).getStatus());

        String resource = propagations.get(0).getResource();
        assertEquals(RESOURCE_NAME_CSV, resource);
    }

    @Test
    public void issue288() {
        UserCR userTO = UserITCase.getSample("issue288@syncope.apache.org");
        userTO.getPlainAttrs().add(attr("aLong", "STRING"));

        try {
            createUser(userTO);
            fail("This should not happen");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.InvalidValues, e.getType());
        }
    }

    @Test
    public void issueSYNCOPE108() {
        UserCR userCR = UserITCase.getUniqueSample("syncope108@syncope.apache.org");
        userCR.getResources().clear();
        userCR.getMemberships().clear();
        userCR.getVirAttrs().clear();
        userCR.getAuxClasses().add("csv");

        userCR.getMemberships().add(new MembershipTO.Builder("0626100b-a4ba-4e00-9971-86fad52a6216").build());
        userCR.getMemberships().add(new MembershipTO.Builder("ba9ed509-b1f5-48ab-a334-c8530a6422dc").build());

        userCR.getResources().add(RESOURCE_NAME_CSV);

        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);
        assertEquals(2, userTO.getMemberships().size());
        assertEquals(1, userTO.getResources().size());

        ConnObjectTO connObjectTO =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
        assertNotNull(connObjectTO);

        // -----------------------------------
        // Remove the first membership: de-provisioning shouldn't happen
        // -----------------------------------
        UserUR userUR = new UserUR.Builder(userTO.getKey()).
                membership(new MembershipUR.Builder(userTO.getMemberships().get(0).getGroupKey()).
                        operation(PatchOperation.DELETE).build()).
                build();

        userTO = updateUser(userUR).getEntity();
        assertNotNull(userTO);
        assertEquals(1, userTO.getMemberships().size());

        connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
        assertNotNull(connObjectTO);
        // -----------------------------------

        // -----------------------------------
        // Remove the resource assigned directly: de-provisioning shouldn't happen
        // -----------------------------------
        userUR = new UserUR();
        userUR.setKey(userTO.getKey());

        userUR.getResources().add(new StringPatchItem.Builder().operation(PatchOperation.DELETE).
                value(userTO.getResources().iterator().next()).build());

        userTO = updateUser(userUR).getEntity();
        assertNotNull(userTO);
        assertEquals(1, userTO.getMemberships().size());
        assertFalse(userTO.getResources().isEmpty());

        connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
        assertNotNull(connObjectTO);
        // -----------------------------------

        // -----------------------------------
        // Remove the first membership: de-provisioning should happen
        // -----------------------------------
        userUR = new UserUR.Builder(userTO.getKey()).
                membership(new MembershipUR.Builder(userTO.getMemberships().get(0).getGroupKey()).
                        operation(PatchOperation.DELETE).build()).
                build();

        userTO = updateUser(userUR).getEntity();
        assertNotNull(userTO);
        assertTrue(userTO.getMemberships().isEmpty());
        assertTrue(userTO.getResources().isEmpty());

        try {
            RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
            fail("Read should not succeeed");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.NotFound, e.getType());
        }
    }

    @Test
    public void issueSYNCOPE185() {
        // 1. create user with LDAP resource, succesfully propagated
        UserCR userCR = UserITCase.getSample("syncope185@syncope.apache.org");
        userCR.getVirAttrs().clear();
        userCR.getResources().add(RESOURCE_NAME_LDAP);

        ProvisioningResult<UserTO> result = createUser(userCR);
        assertNotNull(result);
        assertFalse(result.getPropagationStatuses().isEmpty());
        assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
        assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
        UserTO userTO = result.getEntity();

        // 2. delete this user
        USER_SERVICE.delete(userTO.getKey());

        // 3. try (and fail) to find this user on the external LDAP resource
        try {
            RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
            fail("This entry should not be present on this resource");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.NotFound, e.getType());
        }
    }

    @Test()
    public void issueSYNCOPE51() {
        String originalCA = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
                "password.cipher.algorithm", null, String.class);
        confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", "MD5");

        UserCR userCR = UserITCase.getSample("syncope51@syncope.apache.org");
        userCR.setPassword("password");

        try {
            createUser(userCR);
            fail("Create user should not succeed");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.NotFound, e.getType());
            assertTrue(e.getElements().iterator().next().contains("MD5"));
        } finally {
            confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", originalCA);
        }
    }

    @Test
    public void issueSYNCOPE267() {
        // ----------------------------------
        // create user and check virtual attribute value propagation
        // ----------------------------------
        UserCR userCR = UserITCase.getUniqueSample("syncope267@apache.org");
        userCR.getVirAttrs().add(attr("virtualdata", "virtualvalue"));
        userCR.getResources().clear();
        userCR.getResources().add(RESOURCE_NAME_DBVIRATTR);

        ProvisioningResult<UserTO> result = createUser(userCR);
        assertNotNull(result);
        assertFalse(result.getPropagationStatuses().isEmpty());
        assertEquals(RESOURCE_NAME_DBVIRATTR, result.getPropagationStatuses().get(0).getResource());
        assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
        UserTO userTO = result.getEntity();

        ConnObjectTO connObjectTO =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_DBVIRATTR, AnyTypeKind.USER.name(), userTO.getKey());
        assertNotNull(connObjectTO);
        assertEquals("virtualvalue", connObjectTO.getAttr("USERNAME").get().getValues().get(0));
        // ----------------------------------

        userTO = USER_SERVICE.read(userTO.getKey());

        assertNotNull(userTO);
        assertEquals(1, userTO.getVirAttrs().size());
        assertEquals("virtualvalue", userTO.getVirAttrs().iterator().next().getValues().get(0));
    }

    @Test
    public void issueSYNCOPE266() {
        UserCR userCR = UserITCase.getUniqueSample("syncope266@apache.org");
        userCR.getResources().clear();

        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());

        // this resource has not a mapping for Password
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_UPDATE).build());

        userTO = updateUser(userUR).getEntity();
        assertNotNull(userTO);
    }

    @Test
    public void issueSYNCOPE279() {
        UserCR userCR = UserITCase.getUniqueSample("syncope279@apache.org");
        userCR.getResources().clear();
        userCR.getResources().add(RESOURCE_NAME_TIMEOUT);
        ProvisioningResult<UserTO> result = createUser(userCR);
        assertEquals(RESOURCE_NAME_TIMEOUT, result.getPropagationStatuses().get(0).getResource());
        assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
        assertEquals(ExecStatus.FAILURE, result.getPropagationStatuses().get(0).getStatus());
    }

    @Test
    public void issueSYNCOPE122() {
        // 1. create user on testdb and testdb2
        UserCR userCR = UserITCase.getUniqueSample("syncope122@apache.org");
        userCR.getResources().clear();

        userCR.getResources().add(RESOURCE_NAME_TESTDB);
        userCR.getResources().add(RESOURCE_NAME_TESTDB2);

        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB2));

        String pwdOnSyncope = userTO.getPassword();

        ConnObjectTO userOnDb = RESOURCE_SERVICE.readConnObject(
                RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
        Attr pwdOnTestDbAttr = userOnDb.getAttr(OperationalAttributes.PASSWORD_NAME).get();
        assertNotNull(pwdOnTestDbAttr);
        assertNotNull(pwdOnTestDbAttr.getValues());
        assertFalse(pwdOnTestDbAttr.getValues().isEmpty());
        String pwdOnTestDb = pwdOnTestDbAttr.getValues().get(0);

        ConnObjectTO userOnDb2 = RESOURCE_SERVICE.readConnObject(
                RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
        Attr pwdOnTestDb2Attr = userOnDb2.getAttr(OperationalAttributes.PASSWORD_NAME).get();
        assertNotNull(pwdOnTestDb2Attr);
        assertNotNull(pwdOnTestDb2Attr.getValues());
        assertFalse(pwdOnTestDb2Attr.getValues().isEmpty());
        String pwdOnTestDb2 = pwdOnTestDb2Attr.getValues().get(0);

        // 2. request to change password only on testdb (no Syncope, no testdb2)
        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(new PasswordPatch.Builder().value(getUUIDString()).onSyncope(false).
                resource(RESOURCE_NAME_TESTDB).build());

        ProvisioningResult<UserTO> result = updateUser(userUR);
        userTO = result.getEntity();

        // 3a. Chech that only a single propagation took place
        assertNotNull(result.getPropagationStatuses());
        assertEquals(1, result.getPropagationStatuses().size());
        assertEquals(RESOURCE_NAME_TESTDB, result.getPropagationStatuses().get(0).getResource());

        // 3b. verify that password hasn't changed on Syncope
        assertEquals(pwdOnSyncope, userTO.getPassword());

        // 3c. verify that password *has* changed on testdb
        userOnDb = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
        Attr pwdOnTestDbAttrAfter = userOnDb.getAttr(OperationalAttributes.PASSWORD_NAME).get();
        assertNotNull(pwdOnTestDbAttrAfter);
        assertNotNull(pwdOnTestDbAttrAfter.getValues());
        assertFalse(pwdOnTestDbAttrAfter.getValues().isEmpty());
        assertNotEquals(pwdOnTestDb, pwdOnTestDbAttrAfter.getValues().get(0));

        // 3d. verify that password hasn't changed on testdb2
        userOnDb2 = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
        Attr pwdOnTestDb2AttrAfter = userOnDb2.getAttr(OperationalAttributes.PASSWORD_NAME).get();
        assertNotNull(pwdOnTestDb2AttrAfter);
        assertNotNull(pwdOnTestDb2AttrAfter.getValues());
        assertFalse(pwdOnTestDb2AttrAfter.getValues().isEmpty());
        assertEquals(pwdOnTestDb2, pwdOnTestDb2AttrAfter.getValues().get(0));
    }

    @Test
    public void issueSYNCOPE136AES() {
        // 1. read configured cipher algorithm in order to be able to restore it at the end of test
        String origpwdCipherAlgo = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
                "password.cipher.algorithm", null, String.class);

        // 2. set AES password cipher algorithm
        confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", "AES");

        UserTO userTO = null;
        try {
            // 3. create user with no resources
            UserCR userCR = UserITCase.getUniqueSample("syncope136_AES@apache.org");
            userCR.getResources().clear();

            userTO = createUser(userCR).getEntity();
            assertNotNull(userTO);

            // 4. update user, assign a propagation priority resource but don't provide any password
            UserUR userUR = new UserUR();
            userUR.setKey(userTO.getKey());
            userUR.getResources().add(new StringPatchItem.Builder().
                    operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
            userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());

            ProvisioningResult<UserTO> result = updateUser(userUR);
            assertNotNull(result);
            userTO = result.getEntity();
            assertNotNull(userTO);

            // 5. verify that propagation was successful
            List<PropagationStatus> props = result.getPropagationStatuses();
            assertNotNull(props);
            assertEquals(1, props.size());
            PropagationStatus prop = props.get(0);
            assertNotNull(prop);
            assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
            assertEquals(ExecStatus.SUCCESS, prop.getStatus());
        } finally {
            // restore initial cipher algorithm
            confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", origpwdCipherAlgo);

            if (userTO != null) {
                deleteUser(userTO.getKey());
            }
        }
    }

    @Test
    public void issueSYNCOPE136Random() {
        // 1. create user with no resources
        UserCR userCR = UserITCase.getUniqueSample("syncope136_Random@apache.org");
        userCR.getResources().clear();
        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        // 2. update user, assign a propagation priority resource but don't provide any password
        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
        userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());

        ProvisioningResult<UserTO> result = updateUser(userUR);
        assertNotNull(result);

        // 3. verify that propagation was successful
        List<PropagationStatus> props = result.getPropagationStatuses();
        assertNotNull(props);
        assertEquals(1, props.size());
        PropagationStatus prop = props.get(0);
        assertNotNull(prop);
        assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
        assertEquals(ExecStatus.SUCCESS, prop.getStatus());
    }

    @Test
    public void issueSYNCOPE265() {
        String[] userKeys = new String[] {
            "1417acbe-cbf6-4277-9372-e75e04f97000",
            "74cd8ece-715a-44a4-a736-e17b46c4e7e6",
            "b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee",
            "c9b2dec2-00a7-4855-97c0-d854842b4b24",
            "823074dc-d280-436d-a7dd-07399fae48ec" };

        for (String userKey : userKeys) {
            UserUR userUR = new UserUR();
            userUR.setKey(userKey);
            userUR.getPlainAttrs().add(attrAddReplacePatch("ctype", "a type"));
            UserTO userTO = updateUser(userUR).getEntity();
            assertEquals("a type", userTO.getPlainAttr("ctype").get().getValues().get(0));
        }
    }

    @Test
    public void issueSYNCOPE354() {
        // change resource-ldap group mapping for including uniqueMember (need for assertions below)
        ResourceTO ldap = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
        ldap.getProvision(AnyTypeKind.GROUP.name()).get().getMapping().getItems().stream().
                filter(item -> ("description".equals(item.getExtAttrName()))).
                forEach(item -> item.setExtAttrName("uniqueMember"));
        RESOURCE_SERVICE.update(ldap);

        // 1. create group with LDAP resource
        GroupCR groupCR = new GroupCR();
        groupCR.setName("SYNCOPE354-" + getUUIDString());
        groupCR.setRealm("/");
        groupCR.getResources().add(RESOURCE_NAME_LDAP);

        GroupTO groupTO = createGroup(groupCR).getEntity();
        assertNotNull(groupTO);

        // 2. create user with LDAP resource and membership of the above group
        UserCR userCR = UserITCase.getUniqueSample("syncope354@syncope.apache.org");
        userCR.getResources().add(RESOURCE_NAME_LDAP);
        userCR.getMemberships().add(new MembershipTO.Builder(groupTO.getKey()).build());

        UserTO userTO = createUser(userCR).getEntity();
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
        assertNotNull(RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey()));

        // 3. read group on resource, check that user DN is included in uniqueMember
        ConnObjectTO connObj = RESOURCE_SERVICE.readConnObject(
                RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
        assertNotNull(connObj);
        assertTrue(connObj.getAttr("uniqueMember").get().getValues().
                contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));

        // 4. remove membership
        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.getMemberships().add(new MembershipUR.Builder(userTO.getMemberships().get(0).getGroupKey()).
                operation(PatchOperation.DELETE).build());

        userTO = updateUser(userUR).getEntity();
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));

        // 5. read group on resource, check that user DN was removed from uniqueMember
        connObj = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
        assertNotNull(connObj);
        assertFalse(connObj.getAttr("uniqueMember").get().getValues().
                contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));

        // 6. user has still the LDAP resource assigned - SYNCOPE-1222
        userTO = USER_SERVICE.read(userTO.getKey());
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
        assertNotNull(RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey()));

        // 7. restore original resource-ldap group mapping
        ldap.getProvision(AnyTypeKind.GROUP.name()).get().getMapping().getItems().stream().
                filter(item -> "uniqueMember".equals(item.getExtAttrName())).
                forEach(item -> item.setExtAttrName("description"));
        RESOURCE_SERVICE.update(ldap);
    }

    @Test
    public void issueSYNCOPE357() throws IOException {
        // 1. create group with LDAP resource
        GroupCR groupCR = new GroupCR();
        groupCR.setName("SYNCOPE357-" + getUUIDString());
        groupCR.setRealm("/");
        groupCR.getResources().add(RESOURCE_NAME_LDAP);

        GroupTO groupTO = createGroup(groupCR).getEntity();
        assertNotNull(groupTO);

        // 2. create user with membership of the above group
        UserCR userCR = UserITCase.getUniqueSample("syncope357@syncope.apache.org");
        userCR.getPlainAttrs().add(attr("obscure", "valueToBeObscured"));
        userCR.getPlainAttrs().add(attr("photo", Base64.getEncoder().encodeToString(
                IOUtils.readBytesFromStream(getClass().getResourceAsStream("/favicon.jpg")))));
        userCR.getMemberships().add(new MembershipTO.Builder(groupTO.getKey()).build());

        UserTO userTO = createUser(userCR).getEntity();
        assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
        assertNotNull(userTO.getPlainAttr("obscure"));
        assertNotNull(userTO.getPlainAttr("photo"));

        // 3. read user on resource
        ConnObjectTO connObj = RESOURCE_SERVICE.readConnObject(
                RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
        assertNotNull(connObj);
        Attr registeredAddress = connObj.getAttr("registeredAddress").get();
        assertNotNull(registeredAddress);
        assertEquals(userTO.getPlainAttr("obscure").get().getValues(), registeredAddress.getValues());
        Optional<Attr> jpegPhoto = connObj.getAttr("jpegPhoto");
        assertTrue(jpegPhoto.isPresent());
        assertEquals(userTO.getPlainAttr("photo").get().getValues().get(0), jpegPhoto.get().getValues().get(0));

        // 4. remove group
        GROUP_SERVICE.delete(groupTO.getKey());

        // 5. try to read user on resource: fail
        try {
            RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
            fail("This should not happen");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.NotFound, e.getType());
        }
    }

    @Test
    public void issueSYNCOPE383() {
        // 1. create user without resources
        UserCR userCR = UserITCase.getUniqueSample("syncope383@apache.org");
        userCR.getResources().clear();
        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        // 2. assign resource without specifying a new pwd and check propagation failure
        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());

        ProvisioningResult<UserTO> result = updateUser(userUR);
        assertNotNull(result);
        userTO = result.getEntity();
        assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
        assertNotEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
        assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
        userTO = result.getEntity();

        // 3. request to change password only on testdb
        userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(
                new PasswordPatch.Builder().value(getUUIDString() + "abbcbcbddd123").resource(RESOURCE_NAME_TESTDB).
                        build());

        result = updateUser(userUR);
        assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
        assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
    }

    @Test
    public void issueSYNCOPE402() {
        // 1. create an user with strict mandatory attributes only
        UserCR userCR = new UserCR();
        userCR.setRealm(SyncopeConstants.ROOT_REALM);
        String userId = getUUIDString() + "syncope402@syncope.apache.org";
        userCR.setUsername(userId);
        userCR.setPassword("password123");

        userCR.getPlainAttrs().add(attr("userId", userId));
        userCR.getPlainAttrs().add(attr("fullname", userId));
        userCR.getPlainAttrs().add(attr("surname", userId));

        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);
        assertTrue(userTO.getResources().isEmpty());

        // 2. update assigning a resource NOT forcing mandatory constraints
        // AND priority: must fail with PropagationException
        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
        ProvisioningResult<UserTO> result = updateUser(userUR);

        PropagationStatus ws1PropagationStatus = result.getPropagationStatuses().stream().
                filter(propStatus -> RESOURCE_NAME_WS1.equals(propStatus.getResource())).
                findFirst().orElse(null);
        assertNotNull(ws1PropagationStatus);
        assertEquals(RESOURCE_NAME_WS1, ws1PropagationStatus.getResource());
        assertNotNull(ws1PropagationStatus.getFailureReason());
        assertEquals(ExecStatus.FAILURE, ws1PropagationStatus.getStatus());
    }

    @Test
    public void issueSYNCOPE420() throws IOException {
        ImplementationTO logicActions;
        try {
            logicActions = IMPLEMENTATION_SERVICE.read(
                    IdRepoImplementationType.LOGIC_ACTIONS, "DoubleValueLogicActions");
        } catch (SyncopeClientException e) {
            logicActions = new ImplementationTO();
            logicActions.setKey("DoubleValueLogicActions");
            logicActions.setEngine(ImplementationEngine.GROOVY);
            logicActions.setType(IdRepoImplementationType.LOGIC_ACTIONS);
            logicActions.setBody(org.apache.commons.io.IOUtils.toString(
                    getClass().getResourceAsStream("/DoubleValueLogicActions.groovy"), StandardCharsets.UTF_8));
            Response response = IMPLEMENTATION_SERVICE.create(logicActions);
            logicActions = IMPLEMENTATION_SERVICE.read(
                    logicActions.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
        }
        assertNotNull(logicActions);

        RealmTO realm = REALM_SERVICE.search(new RealmQuery.Builder().keyword("two").build()).getResult().get(0);
        assertNotNull(realm);
        realm.getActions().add(logicActions.getKey());
        REALM_SERVICE.update(realm);

        UserCR userCR = UserITCase.getUniqueSample("syncope420@syncope.apache.org");
        userCR.setRealm(realm.getFullPath());
        userCR.getPlainAttrs().add(attr("makeItDouble", "3"));

        UserTO userTO = createUser(userCR).getEntity();
        assertEquals("6", userTO.getPlainAttr("makeItDouble").get().getValues().get(0));

        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.getPlainAttrs().add(attrAddReplacePatch("makeItDouble", "7"));

        userTO = updateUser(userUR).getEntity();
        assertEquals("14", userTO.getPlainAttr("makeItDouble").get().getValues().get(0));
    }

    @Test
    public void issueSYNCOPE426() {
        UserCR userCR = UserITCase.getUniqueSample("syncope426@syncope.apache.org");
        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(new PasswordPatch.Builder().value("anotherPassword123").build());
        userTO = USER_SERVICE.update(userUR).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
        }).getEntity();
        assertNotNull(userTO);
    }

    @Test
    public void issueSYNCOPE435() {
        // 1. create user without password
        UserCR userCR = UserITCase.getUniqueSample("syncope435@syncope.apache.org");
        userCR.setPassword(null);
        userCR.setStorePassword(false);
        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        // 2. try to update user by subscribing a resource - works but propagation is not even attempted
        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());

        ProvisioningResult<UserTO> result = updateUser(userUR);
        assertNotNull(result);
        userTO = result.getEntity();
        assertEquals(Set.of(RESOURCE_NAME_WS1), userTO.getResources());
        assertNotEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
        assertTrue(result.getPropagationStatuses().get(0).getFailureReason().
                startsWith("Not attempted because there are mandatory attributes without value(s): [__PASSWORD__]"));
    }

    @Test
    public void issueSYNCOPE454() throws NamingException {
        // 1. create user with LDAP resource (with 'Generate password if missing' enabled)
        UserCR userCR = UserITCase.getUniqueSample("syncope454@syncope.apache.org");
        userCR.getResources().add(RESOURCE_NAME_LDAP);
        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        // 2. read resource configuration for LDAP binding
        ConnObjectTO connObject =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());

        // 3. try (and succeed) to perform simple LDAP binding with provided password ('password123')
        assertNotNull(getLdapRemoteObject(
                connObject.getAttr(Name.NAME).get().getValues().get(0),
                "password123",
                connObject.getAttr(Name.NAME).get().getValues().get(0)));

        // 4. update user without any password change request
        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(new PasswordPatch());
        userUR.getPlainAttrs().add(attrAddReplacePatch("surname", "surname2"));

        USER_SERVICE.update(userUR);

        // 5. try (and succeed again) to perform simple LDAP binding: password has not changed
        assertNotNull(getLdapRemoteObject(
                connObject.getAttr(Name.NAME).get().getValues().get(0),
                "password123",
                connObject.getAttr(Name.NAME).get().getValues().get(0)));
    }

    @Test
    public void issueSYNCOPE493() {
        // 1.  create user and check that firstname is not propagated on resource with mapping for firstname set to NONE
        UserCR userCR = UserITCase.getUniqueSample("493@test.org");
        userCR.getResources().add(RESOURCE_NAME_WS1);
        ProvisioningResult<UserTO> result = createUser(userCR);
        assertNotNull(result);
        assertEquals(1, result.getPropagationStatuses().size());
        assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
        UserTO userTO = result.getEntity();

        ConnObjectTO actual =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_WS1, AnyTypeKind.USER.name(), userTO.getKey());
        assertNotNull(actual);
        // check if mapping attribute with purpose NONE really hasn't been propagated
        assertFalse(actual.getAttr("NAME").isPresent());

        // 2.  update resource ws-target-resource-1
        ResourceTO ws1 = RESOURCE_SERVICE.read(RESOURCE_NAME_WS1);
        assertNotNull(ws1);

        MappingTO ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).get().getMapping();
        // change purpose from NONE to BOTH
        for (ItemTO itemTO : ws1NewUMapping.getItems()) {
            if ("firstname".equals(itemTO.getIntAttrName())) {
                itemTO.setPurpose(MappingPurpose.BOTH);
            }
        }

        ws1.getProvision(AnyTypeKind.USER.name()).get().setMapping(ws1NewUMapping);

        RESOURCE_SERVICE.update(ws1);
        ResourceTO newWs1 = RESOURCE_SERVICE.read(ws1.getKey());
        assertNotNull(newWs1);

        // check for existence
        Collection<ItemTO> mapItems = newWs1.getProvision(AnyTypeKind.USER.name()).get().getMapping().getItems();
        assertNotNull(mapItems);
        assertEquals(7, mapItems.size());

        // 3.  update user and check firstname propagation
        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(new PasswordPatch());
        userUR.getPlainAttrs().add(attrAddReplacePatch("firstname", "firstnameNew"));

        result = updateUser(userUR);
        assertNotNull(userTO);
        assertEquals(1, result.getPropagationStatuses().size());
        assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
        userTO = result.getEntity();

        ConnObjectTO newUser =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_WS1, AnyTypeKind.USER.name(), userTO.getKey());

        assertNotNull(newUser.getAttr("NAME"));
        assertEquals("firstnameNew", newUser.getAttr("NAME").get().getValues().get(0));

        // 4.  restore resource ws-target-resource-1 mapping
        ws1NewUMapping = newWs1.getProvision(AnyTypeKind.USER.name()).get().getMapping();
        // restore purpose from BOTH to NONE
        for (ItemTO itemTO : ws1NewUMapping.getItems()) {
            if ("firstname".equals(itemTO.getIntAttrName())) {
                itemTO.setPurpose(MappingPurpose.NONE);
            }
        }

        newWs1.getProvision(AnyTypeKind.USER.name()).get().setMapping(ws1NewUMapping);

        RESOURCE_SERVICE.update(newWs1);
    }

    @Test
    public void issueSYNCOPE505DB() throws Exception {
        // 1. create user
        UserCR userCR = UserITCase.getUniqueSample("syncope505-db@syncope.apache.org");
        userCR.setPassword("security123");
        UserTO user = createUser(userCR).getEntity();
        assertNotNull(user);
        assertTrue(user.getResources().isEmpty());

        // 2. Add DBPasswordPropagationActions
        ImplementationTO propagationActions = new ImplementationTO();
        propagationActions.setKey(DBPasswordPropagationActions.class.getSimpleName());
        propagationActions.setEngine(ImplementationEngine.JAVA);
        propagationActions.setType(IdMImplementationType.PROPAGATION_ACTIONS);
        propagationActions.setBody(DBPasswordPropagationActions.class.getName());
        Response response = IMPLEMENTATION_SERVICE.create(propagationActions);
        propagationActions = IMPLEMENTATION_SERVICE.read(
                propagationActions.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
        assertNotNull(propagationActions);

        ResourceTO resourceTO = RESOURCE_SERVICE.read(RESOURCE_NAME_TESTDB);
        assertNotNull(resourceTO);
        resourceTO.getPropagationActions().add(propagationActions.getKey());
        RESOURCE_SERVICE.update(resourceTO);

        // 3. Add a db resource to the User
        UserUR userUR = new UserUR();
        userUR.setKey(user.getKey());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());

        userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_TESTDB).build());

        user = updateUser(userUR).getEntity();
        assertNotNull(user);
        assertEquals(1, user.getResources().size());

        // 4. Check that the DB resource has the correct password
        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
        String value = jdbcTemplate.queryForObject(
                "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
        assertEquals(Encryptor.getInstance().encode("security123", CipherAlgorithm.SHA1), value.toUpperCase());

        // 5. Remove DBPasswordPropagationActions
        resourceTO = RESOURCE_SERVICE.read(RESOURCE_NAME_TESTDB);
        assertNotNull(resourceTO);
        resourceTO.getPropagationActions().remove(propagationActions.getKey());
        RESOURCE_SERVICE.update(resourceTO);
    }

    @Test
    public void issueSYNCOPE505LDAP() throws Exception {
        // 1. create user
        UserCR userCR = UserITCase.getUniqueSample("syncope505-ldap@syncope.apache.org");
        userCR.setPassword("security123");
        UserTO user = createUser(userCR).getEntity();
        assertNotNull(user);
        assertTrue(user.getResources().isEmpty());

        // 2. Add LDAPPasswordPropagationActions
        ImplementationTO propagationActions = new ImplementationTO();
        propagationActions.setKey(LDAPPasswordPropagationActions.class.getSimpleName());
        propagationActions.setEngine(ImplementationEngine.JAVA);
        propagationActions.setType(IdMImplementationType.PROPAGATION_ACTIONS);
        propagationActions.setBody(LDAPPasswordPropagationActions.class.getName());
        Response response = IMPLEMENTATION_SERVICE.create(propagationActions);
        propagationActions = IMPLEMENTATION_SERVICE.read(
                propagationActions.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
        assertNotNull(propagationActions);

        ResourceTO resourceTO = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
        assertNotNull(resourceTO);
        resourceTO.getPropagationActions().add(propagationActions.getKey());
        resourceTO.setRandomPwdIfNotProvided(false);
        RESOURCE_SERVICE.update(resourceTO);

        // 3. Add a resource to the User
        UserUR userUR = new UserUR();
        userUR.setKey(user.getKey());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());

        userUR.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());

        user = updateUser(userUR).getEntity();
        assertNotNull(user);
        assertEquals(1, user.getResources().size());

        // 4. Check that the LDAP resource has the correct password
        ConnObjectTO connObject =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());

        assertNotNull(getLdapRemoteObject(
                connObject.getAttr(Name.NAME).get().getValues().get(0),
                "security123",
                connObject.getAttr(Name.NAME).get().getValues().get(0)));

        // 5. Remove LDAPPasswordPropagationActions
        resourceTO = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP);
        assertNotNull(resourceTO);
        resourceTO.getPropagationActions().remove(propagationActions.getKey());
        resourceTO.setRandomPwdIfNotProvided(true);
        RESOURCE_SERVICE.update(resourceTO);
    }

    @Test
    public void issueSYNCOPE391() {
        assumeFalse(ElasticsearchDetector.isElasticSearchEnabled(ADMIN_CLIENT.platform()));

        // 1. create user on Syncope with null password
        UserCR userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org");
        userCR.setPassword(null);
        userCR.setStorePassword(false);

        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);
        assertNull(userTO.getPassword());

        // 2. create existing user on csv and check that password on Syncope is null and that password on resource
        // doesn't change
        userCR = new UserCR();
        userCR.setRealm(SyncopeConstants.ROOT_REALM);
        userCR.setPassword(null);
        userCR.setStorePassword(false);
        userCR.setUsername("syncope391@syncope.apache.org");
        userCR.getPlainAttrs().add(attr("fullname", "fullname"));
        userCR.getPlainAttrs().add(attr("firstname", "nome0"));
        userCR.getPlainAttrs().add(attr("surname", "cognome0"));
        userCR.getPlainAttrs().add(attr("userId", "syncope391@syncope.apache.org"));
        userCR.getPlainAttrs().add(attr("email", "syncope391@syncope.apache.org"));
        userCR.getAuxClasses().add("csv");
        userCR.getResources().add(RESOURCE_NAME_CSV);

        userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        ConnObjectTO connObjectTO =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
        assertNotNull(connObjectTO);

        // check if password has not changed
        assertEquals("password0", connObjectTO.getAttr(OperationalAttributes.PASSWORD_NAME).get().getValues().get(0));
        assertNull(userTO.getPassword());

        // 3. create user with not null password and propagate onto resource-csv, specify not to save password on
        // Syncope local storage
        userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org");
        userCR.setPassword("passwordTESTNULL1");
        userCR.setStorePassword(false);
        userCR.getVirAttrs().clear();
        userCR.getAuxClasses().add("csv");
        userCR.getResources().add(RESOURCE_NAME_CSV);

        userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        connObjectTO =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
        assertNotNull(connObjectTO);

        // check if password has been propagated and that saved userTO's password is null
        assertEquals(
                "passwordTESTNULL1",
                connObjectTO.getAttr(OperationalAttributes.PASSWORD_NAME).get().getValues().get(0));
        assertNull(userTO.getPassword());

        // 4. create user and propagate password on resource-csv and on Syncope local storage
        userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org");
        userCR.setPassword("passwordTESTNULL1");
        userCR.getVirAttrs().clear();
        userCR.getAuxClasses().add("csv");
        userCR.getResources().add(RESOURCE_NAME_CSV);

        // storePassword true by default
        userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
        assertNotNull(connObjectTO);

        // check if password has been correctly propagated on Syncope and resource-csv as usual
        assertEquals(
                "passwordTESTNULL1",
                connObjectTO.getAttr(OperationalAttributes.PASSWORD_NAME).get().getValues().get(0));
        Triple<Map<String, Set<String>>, List<String>, UserTO> self =
                CLIENT_FACTORY.create(userTO.getUsername(), "passwordTESTNULL1").self();
        assertNotNull(self);

        // 4. add password policy to resource with passwordNotStore to false --> must store password
        ResourceTO csv = RESOURCE_SERVICE.read(RESOURCE_NAME_CSV);
        assertNotNull(csv);
        try {
            csv.setPasswordPolicy("55e5de0b-c79c-4e66-adda-251b6fb8579a");
            RESOURCE_SERVICE.update(csv);
            csv = RESOURCE_SERVICE.read(RESOURCE_NAME_CSV);
            assertEquals("55e5de0b-c79c-4e66-adda-251b6fb8579a", csv.getPasswordPolicy());

            userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org");
            userCR.setPassword(null);
            userCR.setStorePassword(false);
            userCR.getVirAttrs().clear();
            userCR.getAuxClasses().add("csv");
            userCR.getResources().add(RESOURCE_NAME_CSV);

            createUser(userCR);
            fail("This should not happen");
        } catch (SyncopeClientException e) {
            assertEquals(ClientExceptionType.InvalidUser, e.getType());
            assertTrue(e.getMessage().contains("Password mandatory"));
        } finally {
            // resource csv with null password policy
            csv.setPasswordPolicy(null);
            RESOURCE_SERVICE.update(csv);
        }
    }

    @Test
    public void issueSYNCOPE647() {
        UserCR userCR = UserITCase.getUniqueSample("syncope647@syncope.apache.org");
        userCR.getResources().clear();
        userCR.getMemberships().clear();
        userCR.getVirAttrs().clear();
        userCR.getAuxClasses().add("csv");

        userCR.getAuxClasses().add("generic membership");
        userCR.getPlainAttrs().add(attr("postalAddress", "postalAddress"));

        userCR.getResources().add(RESOURCE_NAME_LDAP);

        UserTO actual = createUser(userCR).getEntity();
        assertNotNull(actual);
        assertNotNull(actual.getDerAttr("csvuserid"));

        ConnObjectTO connObjectTO =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), actual.getKey());
        assertNotNull(connObjectTO);
        assertEquals("postalAddress", connObjectTO.getAttr("postalAddress").get().getValues().get(0));

        UserUR userUR = new UserUR();
        userUR.setKey(actual.getKey());
        userUR.getPlainAttrs().add(attrAddReplacePatch("postalAddress", "newPostalAddress"));

        actual = updateUser(userUR).getEntity();

        connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), actual.getKey());
        assertNotNull(connObjectTO);
        assertEquals("newPostalAddress", connObjectTO.getAttr("postalAddress").get().getValues().get(0));
    }

    @Test
    public void issueSYNCOPE626() {
        DefaultPasswordRuleConf ruleConf = new DefaultPasswordRuleConf();
        ruleConf.setUsernameAllowed(false);

        ImplementationTO rule = new ImplementationTO();
        rule.setKey("DefaultPasswordRuleConf" + getUUIDString());
        rule.setEngine(ImplementationEngine.JAVA);
        rule.setType(IdRepoImplementationType.PASSWORD_RULE);
        rule.setBody(POJOHelper.serialize(ruleConf));
        Response response = IMPLEMENTATION_SERVICE.create(rule);
        rule.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY));

        PasswordPolicyTO passwordPolicy = new PasswordPolicyTO();
        passwordPolicy.setName("Password Policy for SYNCOPE-626");
        passwordPolicy.getRules().add(rule.getKey());

        passwordPolicy = createPolicy(PolicyType.PASSWORD, passwordPolicy);
        assertNotNull(passwordPolicy);

        RealmTO realm = REALM_SERVICE.search(new RealmQuery.Builder().keyword("two").build()).getResult().get(0);
        String oldPasswordPolicy = realm.getPasswordPolicy();
        realm.setPasswordPolicy(passwordPolicy.getKey());
        REALM_SERVICE.update(realm);

        try {
            UserCR userCR = UserITCase.getUniqueSample("syncope626@syncope.apache.org");
            userCR.setRealm(realm.getFullPath());
            userCR.setPassword(userCR.getUsername());
            try {
                createUser(userCR);
                fail("This should not happen");
            } catch (SyncopeClientException e) {
                assertEquals(ClientExceptionType.InvalidUser, e.getType());
                assertTrue(e.getElements().iterator().next().startsWith("InvalidPassword"));
            }

            userCR.setPassword("password123");
            UserTO user = createUser(userCR).getEntity();
            assertNotNull(user);
        } finally {
            realm.setPasswordPolicy(oldPasswordPolicy);
            REALM_SERVICE.update(realm);

            POLICY_SERVICE.delete(PolicyType.PASSWORD, passwordPolicy.getKey());
        }

    }

    @Test
    public void issueSYNCOPE686() {
        // 1. read configured cipher algorithm in order to be able to restore it at the end of test
        String origpwdCipherAlgo = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
                "password.cipher.algorithm", null, String.class);

        // 2. set AES password cipher algorithm
        confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", "AES");

        try {
            // 3. create group with LDAP resource assigned
            GroupCR groupCR = GroupITCase.getBasicSample("syncope686");
            groupCR.getResources().add(RESOURCE_NAME_LDAP);
            GroupTO group = createGroup(groupCR).getEntity();
            assertNotNull(group);

            // 4. create user with no resources
            UserCR userCR = UserITCase.getUniqueSample("syncope686@apache.org");
            userCR.getResources().clear();

            UserTO userTO = createUser(userCR).getEntity();
            assertNotNull(userTO);

            // 5. update user with the new group, and don't provide any password
            UserUR userUR = new UserUR();
            userUR.setKey(userTO.getKey());
            userUR.getMemberships().add(new MembershipUR.Builder(group.getKey()).
                    operation(PatchOperation.ADD_REPLACE).build());

            ProvisioningResult<UserTO> result = updateUser(userUR);
            assertNotNull(result);

            // 5. verify that propagation was successful
            List<PropagationStatus> props = result.getPropagationStatuses();
            assertNotNull(props);
            assertEquals(1, props.size());
            PropagationStatus prop = props.get(0);
            assertNotNull(prop);
            assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
            assertEquals(ExecStatus.SUCCESS, prop.getStatus());
        } finally {
            // restore initial cipher algorithm
            confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", origpwdCipherAlgo);
        }
    }

    @Test
    public void issueSYNCOPE710() {
        // 1. create groups for indirect resource assignment
        GroupCR ldapGroupCR = GroupITCase.getBasicSample("syncope710.ldap");
        ldapGroupCR.getResources().add(RESOURCE_NAME_LDAP);
        GroupTO ldapGroup = createGroup(ldapGroupCR).getEntity();

        GroupCR dbGroupCR = GroupITCase.getBasicSample("syncope710.db");
        dbGroupCR.getResources().add(RESOURCE_NAME_TESTDB);
        GroupTO dbGroup = createGroup(dbGroupCR).getEntity();

        // 2. create user with memberships for the groups created above
        UserCR userCR = UserITCase.getUniqueSample("syncope710@syncope.apache.org");
        userCR.getResources().clear();
        userCR.getMemberships().clear();
        userCR.getMemberships().add(new MembershipTO.Builder(ldapGroup.getKey()).build());
        userCR.getMemberships().add(new MembershipTO.Builder(dbGroup.getKey()).build());

        ProvisioningResult<UserTO> result = createUser(userCR);
        assertEquals(2, result.getPropagationStatuses().size());
        UserTO userTO = result.getEntity();

        // 3. request to propagate password only to db
        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        userUR.setPassword(new PasswordPatch.Builder().
                onSyncope(false).resource(RESOURCE_NAME_TESTDB).value("newpassword123").build());

        result = updateUser(userUR);
        assertEquals(1, result.getPropagationStatuses().size());
        assertEquals(RESOURCE_NAME_TESTDB, result.getPropagationStatuses().get(0).getResource());
    }

    @Test
    public void issueSYNCOPE881() {
        // 1. create group and assign LDAP
        GroupCR groupCR = GroupITCase.getSample("syncope881G");
        groupCR.getVirAttrs().add(attr("rvirtualdata", "rvirtualvalue"));

        GroupTO group = createGroup(groupCR).getEntity();
        assertNotNull(group);
        assertNotNull(RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), group.getKey()));

        // 2. create user and assign such group
        UserCR userCR = UserITCase.getUniqueSample("syncope881U@apache.org");
        userCR.getMemberships().clear();
        userCR.getMemberships().add(new MembershipTO.Builder(group.getKey()).build());

        UserTO user = createUser(userCR).getEntity();
        assertNotNull(user);

        // 3. verify that user is in LDAP
        ConnObjectTO connObject =
                RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
        assertNotNull(connObject);
        Attr userDn = connObject.getAttr(Name.NAME).get();
        assertNotNull(userDn);
        assertEquals(1, userDn.getValues().size());
        assertNotNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, userDn.getValues().get(0)));

        // 4. remove user
        USER_SERVICE.delete(user.getKey());

        // 5. verify that user is not in LDAP anymore
        assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, userDn.getValues().get(0)));
    }

    @Test
    public void issueSYNCOPE1099() {
        // 1. create group with dynamic condition and resource
        GroupCR groupCR = GroupITCase.getSample("syncope1099G");
        groupCR.getResources().clear();
        groupCR.getResources().add(RESOURCE_NAME_TESTDB);
        groupCR.setUDynMembershipCond("firstname==issueSYNCOPE1099");

        GroupTO group = createGroup(groupCR).getEntity();
        assertNotNull(group);

        // 2. create user matching the condition above
        UserCR userCR = UserITCase.getUniqueSample("syncope1099U@apache.org");
        userCR.getPlainAttr("firstname").get().getValues().set(0, "issueSYNCOPE1099");

        ProvisioningResult<UserTO> created = createUser(userCR);
        assertNotNull(created);

        // 3. verify that dynamic membership is set and that resource is consequently assigned
        UserTO user = created.getEntity();
        String groupKey = group.getKey();
        assertTrue(user.getDynMemberships().stream().anyMatch(m -> m.getGroupKey().equals(groupKey)));
        assertTrue(user.getResources().contains(RESOURCE_NAME_TESTDB));

        // 4. verify that propagation happened towards the resource of the dynamic group
        assertFalse(created.getPropagationStatuses().isEmpty());
        assertEquals(RESOURCE_NAME_TESTDB, created.getPropagationStatuses().get(0).getResource());
    }

    @Test
    public void issueSYNCOPE1166() {
        UserCR userCR = UserITCase.getUniqueSample("syncope1166@apache.org");
        UserTO userTO = createUser(userCR).getEntity();
        assertNotNull(userTO);

        UserUR userUR = new UserUR();
        userUR.setKey(userTO.getKey());
        // resource-ldap has password mapped, resource-db-virattr does not
        userUR.setPassword(new PasswordPatch.Builder().
                onSyncope(true).
                resource(RESOURCE_NAME_LDAP).
                value("new2Password").build());

        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
        userUR.getResources().add(new StringPatchItem.Builder().
                operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_DBVIRATTR).build());

        ProvisioningResult<UserTO> result = updateUser(userUR);
        assertNotNull(result);
        assertEquals(2, result.getPropagationStatuses().size());
        assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
        assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
        assertEquals(RESOURCE_NAME_DBVIRATTR, result.getPropagationStatuses().get(1).getResource());
        assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(1).getStatus());
    }

    @Test
    public void issueSYNCOPE1206() {
        // 1. create group with dynamic user condition 'cool==true'
        GroupCR dynGroupCR = GroupITCase.getSample("syncope1206");
        dynGroupCR.setUDynMembershipCond(
                SyncopeClient.getUserSearchConditionBuilder().is("cool").equalTo("true").query());
        GroupTO dynGroup = createGroup(dynGroupCR).getEntity();
        assertNotNull(dynGroup);
        assertTrue(dynGroup.getResources().contains(RESOURCE_NAME_LDAP));

        // 2. create user (no value for cool, no dynamic membership, no propagation to LDAP)
        UserCR userCR = UserITCase.getUniqueSample("syncope1206@apache.org");
        userCR.getResources().clear();

        ProvisioningResult<UserTO> result = createUser(userCR);
        assertTrue(result.getPropagationStatuses().isEmpty());

        // 3. update user to match the dynamic condition: expect propagation to LDAP
        UserUR userUR = new UserUR();
        userUR.setKey(result.getEntity().getKey());
        userUR.getPlainAttrs().add(new AttrPatch.Builder(attr("cool", "true")).build());

        result = updateUser(userUR);
        assertEquals(1, result.getPropagationStatuses().size());
        assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());

        // 4. update again user to not match the dynamic condition any more: expect propagation to LDAP
        userUR = new UserUR();
        userUR.setKey(result.getEntity().getKey());
        userUR.getPlainAttrs().add(new AttrPatch.Builder(attr("cool", "false")).build());

        result = updateUser(userUR);
        assertEquals(1, result.getPropagationStatuses().size());
        assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
    }

    @Test
    public void issueSYNCOPE1337() {
        // 1. save current cipher algorithm and set it to something salted
        String original = confParamOps.get(SyncopeConstants.MASTER_DOMAIN,
                "password.cipher.algorithm", null, String.class);

        confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", CipherAlgorithm.SSHA512.name());

        try {
            // 2. create user under /even/two to get password policy with history length 1
            UserCR userCR = UserITCase.getUniqueSample("syncope1337@apache.org");
            userCR.setPassword("Password123");
            userCR.setRealm("/even/two");
            UserTO userTO = createUser(userCR).getEntity();
            assertNotNull(userTO);

            // 3. attempt to set the same password value: fails
            UserUR req = new UserUR();
            req.setKey(userTO.getKey());
            req.setPassword(new PasswordPatch.Builder().onSyncope(true).value("Password123").build());
            try {
                updateUser(req);
                fail("Password update should not work");
            } catch (SyncopeClientException e) {
                assertEquals(ClientExceptionType.InvalidUser, e.getType());
                assertTrue(e.getMessage().contains("InvalidPassword"));
            }

            // 4. set another password value: works
            req.setPassword(new PasswordPatch.Builder().onSyncope(true).value("Password124").build());
            userTO = updateUser(req).getEntity();
            assertNotNull(userTO);

            // 5. set the original password value: works (history length is 1)
            req.setPassword(new PasswordPatch.Builder().onSyncope(true).value("Password123").build());
            userTO = updateUser(req).getEntity();
            assertNotNull(userTO);
        } finally {
            // finally revert the cipher algorithm
            confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "password.cipher.algorithm", original);
        }
    }

    @Test
    public void issueSYNCOPE1472() {
        // 1. update user rossini by assigning twice resource-testdb2 and auxiliary class csv
        UserUR userUR = new UserUR();
        userUR.setKey("1417acbe-cbf6-4277-9372-e75e04f97000");
        userUR.setPassword(new PasswordPatch.Builder()
                .onSyncope(false)
                .resource(RESOURCE_NAME_TESTDB)
                .value("Password123")
                .build());
        userUR.getResources().add(new StringPatchItem.Builder()
                .value(RESOURCE_NAME_TESTDB)
                .operation(PatchOperation.ADD_REPLACE)
                .build());
        userUR.getAuxClasses().add(new StringPatchItem.Builder()
                .operation(PatchOperation.ADD_REPLACE)
                .value("csv")
                .build());
        userUR.getRoles().add(new StringPatchItem.Builder()
                .operation(PatchOperation.ADD_REPLACE)
                .value("Other")
                .build());

        for (int i = 0; i < 2; i++) {
            updateUser(userUR);
        }

        // 2. remove resources, auxiliary classes and roles
        userUR.getResources().clear();
        userUR.getResources().add(new StringPatchItem.Builder()
                .value(RESOURCE_NAME_TESTDB)
                .operation(PatchOperation.DELETE)
                .build());
        userUR.getAuxClasses().clear();
        userUR.getAuxClasses().add(new StringPatchItem.Builder()
                .value("csv")
                .operation(PatchOperation.DELETE)
                .build());
        userUR.getRoles().clear();
        userUR.getRoles().add(new StringPatchItem.Builder()
                .value("Other")
                .operation(PatchOperation.DELETE)
                .build());
        updateUser(userUR);

        UserTO userTO = USER_SERVICE.read("1417acbe-cbf6-4277-9372-e75e04f97000");
        assertFalse(userTO.getResources().contains(RESOURCE_NAME_TESTDB), "Should not contain removed resources");
        assertFalse(userTO.getAuxClasses().contains("csv"), "Should not contain removed auxiliary classes");
        assertFalse(userTO.getRoles().contains("Other"), "Should not contain removed roles");
    }
}
