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

[5/5] syncope git commit: Merge from 1_2_X

Merge from 1_2_X


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/4bd99d3b
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/4bd99d3b
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/4bd99d3b

Branch: refs/heads/master
Commit: 4bd99d3b5eb62e0cb7b4a546b18ea12297444f82
Parents: f45f2d9 81a6644
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jul 13 12:30:40 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jul 13 12:30:40 2015 +0200

----------------------------------------------------------------------
 .../core/persistence/api/entity/AccountPolicy.java   |  4 ++--
 .../persistence/jpa/dao/JPAExternalResourceDAO.java  |  2 +-
 .../persistence/jpa/entity/JPAAccountPolicy.java     |  4 ++--
 .../syncope/fit/core/reference/PolicyITCase.java     | 15 +++++++++++++++
 4 files changed, 20 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/4bd99d3b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccountPolicy.java
----------------------------------------------------------------------
diff --cc core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccountPolicy.java
index 7a743c2,0000000..bafc554
mode 100644,000000..100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccountPolicy.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccountPolicy.java
@@@ -1,33 -1,0 +1,33 @@@
 +/*
 + * 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.core.persistence.api.entity;
 +
 +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 +import java.util.Set;
 +
 +public interface AccountPolicy extends Policy {
 +
-     boolean addResource(ExternalResource resource);
++    boolean add(ExternalResource resource);
 +
-     boolean removeResource(ExternalResource resource);
++    boolean remove(ExternalResource resource);
 +
 +    Set<String> getResourceNames();
 +
 +    Set<? extends ExternalResource> getResources();
 +}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4bd99d3b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --cc core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index b13a8bd,0000000..35a5b00
mode 100644,000000..100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@@ -1,228 -1,0 +1,228 @@@
 +/*
 + * 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.core.persistence.jpa.dao;
 +
 +import java.util.HashSet;
 +import java.util.List;
 +import java.util.Set;
 +import javax.persistence.TypedQuery;
 +import org.apache.syncope.common.lib.types.IntMappingType;
 +import org.apache.syncope.common.lib.types.PolicyType;
 +import org.apache.syncope.common.lib.types.TaskType;
 +import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 +import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 +import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 +import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 +import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 +import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 +import org.apache.syncope.core.persistence.api.dao.UserDAO;
 +import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 +import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 +import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 +import org.apache.syncope.core.persistence.api.entity.Policy;
 +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 +import org.apache.syncope.core.persistence.api.entity.group.Group;
 +import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 +import org.apache.syncope.core.persistence.api.entity.user.User;
 +import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
 +import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 +import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
 +import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
 +import org.springframework.beans.factory.annotation.Autowired;
 +import org.springframework.stereotype.Repository;
 +import org.springframework.transaction.annotation.Transactional;
 +
 +@Repository
 +public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String> implements ExternalResourceDAO {
 +
 +    @Autowired
 +    private TaskDAO taskDAO;
 +
 +    @Autowired
 +    private AnyObjectDAO anyObjectDAO;
 +
 +    @Autowired
 +    private UserDAO userDAO;
 +
 +    @Autowired
 +    private GroupDAO groupDAO;
 +
 +    @Autowired
 +    private PolicyDAO policyDAO;
 +
 +    @Autowired
 +    private ConnectorRegistry connRegistry;
 +
 +    @Autowired
 +    private AnyUtilsFactory anyUtilsFactory;
 +
 +    @Override
 +    public ExternalResource find(final String name) {
 +        return entityManager.find(JPAExternalResource.class, name);
 +    }
 +
 +    private StringBuilder getByPolicyQuery(final PolicyType type) {
 +        StringBuilder query = new StringBuilder("SELECT e FROM ").
 +                append(JPAExternalResource.class.getSimpleName()).
 +                append(" e WHERE e.");
 +        switch (type) {
 +            case ACCOUNT:
 +                query.append("accountPolicy");
 +                break;
 +
 +            case PASSWORD:
 +                query.append("passwordPolicy");
 +                break;
 +
 +            case SYNC:
 +                query.append("syncPolicy");
 +                break;
 +
 +            default:
 +                break;
 +        }
 +        return query;
 +    }
 +
 +    @Override
 +    public List<ExternalResource> findByPolicy(final Policy policy) {
 +        TypedQuery<ExternalResource> query = entityManager.createQuery(
 +                getByPolicyQuery(policy.getType()).append(" = :policy").toString(), ExternalResource.class);
 +        query.setParameter("policy", policy);
 +        return query.getResultList();
 +    }
 +
 +    @Override
 +    public List<ExternalResource> findWithoutPolicy(final PolicyType type) {
 +        TypedQuery<ExternalResource> query = entityManager.createQuery(
 +                getByPolicyQuery(type).append(" IS NULL").toString(), ExternalResource.class);
 +        return query.getResultList();
 +    }
 +
 +    @Override
 +    public List<ExternalResource> findAll() {
 +        TypedQuery<ExternalResource> query = entityManager.createQuery(
 +                "SELECT e FROM  " + JPAExternalResource.class.getSimpleName() + " e", ExternalResource.class);
 +        return query.getResultList();
 +    }
 +
 +    @Override
 +    public List<ExternalResource> findAllByPriority() {
 +        TypedQuery<ExternalResource> query = entityManager.createQuery(
 +                "SELECT e FROM  " + JPAExternalResource.class.getSimpleName() + " e ORDER BY e.propagationPriority",
 +                ExternalResource.class);
 +        return query.getResultList();
 +    }
 +
 +    /**
 +     * This method has an explicit Transactional annotation because it is called by SyncJob.
 +     *
 +     * @see org.apache.syncope.core.sync.impl.SyncJob
 +     *
 +     * @param resource entity to be merged
 +     * @return the same entity, updated
 +     */
 +    @Override
 +    @Transactional(rollbackFor = { Throwable.class })
 +    public ExternalResource save(final ExternalResource resource) {
 +        ExternalResource merged = entityManager.merge(resource);
 +        try {
 +            connRegistry.registerConnector(merged);
 +        } catch (NotFoundException e) {
 +            LOG.error("While registering connector for resource", e);
 +        }
 +        return merged;
 +    }
 +
 +    @Override
 +    @SuppressWarnings("unchecked")
 +    public void deleteMapping(final String intAttrName, final IntMappingType intMappingType) {
 +        if (IntMappingType.getEmbedded().contains(intMappingType)) {
 +            return;
 +        }
 +
 +        TypedQuery<MappingItem> query = entityManager.createQuery(
 +                "SELECT m FROM " + JPAMappingItem.class.getSimpleName()
 +                + " m WHERE m.intAttrName=:intAttrName AND m.intMappingType=:intMappingType", MappingItem.class);
 +        query.setParameter("intAttrName", intAttrName);
 +        query.setParameter("intMappingType", intMappingType);
 +
 +        Set<Long> itemKeys = new HashSet<>();
 +        for (MappingItem item : query.getResultList()) {
 +            itemKeys.add(item.getKey());
 +        }
 +        for (Long itemKey : itemKeys) {
 +            MappingItem item = entityManager.find(JPAMappingItem.class, itemKey);
 +            if (item != null) {
 +                item.getMapping().remove(item);
 +                item.setMapping(null);
 +
 +                entityManager.remove(item);
 +            }
 +        }
 +
 +        // Make empty query cache for *MappingItem and related *Mapping
 +        entityManager.getEntityManagerFactory().getCache().evict(JPAMappingItem.class);
 +        entityManager.getEntityManagerFactory().getCache().evict(JPAMapping.class);
 +    }
 +
 +    @Override
 +    public void delete(final String name) {
 +        ExternalResource resource = find(name);
 +        if (resource == null) {
 +            return;
 +        }
 +
 +        taskDAO.deleteAll(resource, TaskType.PROPAGATION);
 +        taskDAO.deleteAll(resource, TaskType.SYNCHRONIZATION);
 +        taskDAO.deleteAll(resource, TaskType.PUSH);
 +
 +        for (AnyObject anyObject : anyObjectDAO.findByResource(resource)) {
 +            anyObject.remove(resource);
 +        }
 +        for (User user : userDAO.findByResource(resource)) {
 +            user.remove(resource);
 +        }
 +        for (Group group : groupDAO.findByResource(resource)) {
 +            group.remove(resource);
 +        }
 +        for (AccountPolicy policy : policyDAO.findByResource(resource)) {
-             policy.removeResource(resource);
++            policy.remove(resource);
 +        }
 +
 +        if (resource.getConnector() != null && resource.getConnector().getResources() != null
 +                && !resource.getConnector().getResources().isEmpty()) {
 +
 +            resource.getConnector().getResources().remove(resource);
 +        }
 +        resource.setConnector(null);
 +
 +        for (Provision provision : resource.getProvisions()) {
 +            for (MappingItem item : provision.getMapping().getItems()) {
 +                item.setMapping(null);
 +            }
 +            provision.getMapping().getItems().clear();
 +            provision.setMapping(null);
 +            provision.setResource(null);
 +        }
 +
 +        entityManager.remove(resource);
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4bd99d3b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
----------------------------------------------------------------------
diff --cc core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
index 6949817,0000000..64475aa
mode 100644,000000..100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
@@@ -1,84 -1,0 +1,84 @@@
 +/*
 + * 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.core.persistence.jpa.entity;
 +
 +import java.util.HashSet;
 +import java.util.Set;
 +import javax.persistence.DiscriminatorValue;
 +import javax.persistence.Entity;
 +import javax.persistence.FetchType;
 +import javax.persistence.JoinColumn;
 +import javax.persistence.JoinTable;
 +import javax.persistence.ManyToMany;
 +import org.apache.commons.collections4.CollectionUtils;
 +import org.apache.commons.collections4.Transformer;
 +import org.apache.syncope.common.lib.types.PolicyType;
 +import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 +import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 +
 +@Entity
 +@DiscriminatorValue("AccountPolicy")
 +public class JPAAccountPolicy extends JPAPolicy implements AccountPolicy {
 +
 +    private static final long serialVersionUID = -2767606675667839060L;
 +
 +    /**
 +     * Resources for alternative user authentication: if empty, only internal storage will be used.
 +     */
 +    @ManyToMany(fetch = FetchType.EAGER)
 +    @JoinTable(joinColumns =
 +            @JoinColumn(name = "accountPolicy_id"),
 +            inverseJoinColumns =
 +            @JoinColumn(name = "resource_name"))
 +    private Set<JPAExternalResource> resources = new HashSet<>();
 +
 +    public JPAAccountPolicy() {
 +        super();
 +        this.type = PolicyType.ACCOUNT;
 +    }
 +
 +    @Override
-     public boolean addResource(final ExternalResource resource) {
++    public boolean add(final ExternalResource resource) {
 +        checkType(resource, JPAExternalResource.class);
 +        return resources.add((JPAExternalResource) resource);
 +    }
 +
 +    @Override
-     public boolean removeResource(final ExternalResource resource) {
++    public boolean remove(final ExternalResource resource) {
 +        checkType(resource, JPAExternalResource.class);
 +        return resources.remove((JPAExternalResource) resource);
 +    }
 +
 +    @Override
 +    public Set<? extends ExternalResource> getResources() {
 +        return resources;
 +    }
 +
 +    @Override
 +    public Set<String> getResourceNames() {
 +        return CollectionUtils.collect(getResources(), new Transformer<ExternalResource, String>() {
 +
 +            @Override
 +            public String transform(final ExternalResource input) {
 +                return input.getKey();
 +            }
 +        }, new HashSet<String>());
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4bd99d3b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
----------------------------------------------------------------------
diff --cc fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
index 3684f35,0000000..0098821
mode 100644,000000..100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
@@@ -1,188 -1,0 +1,203 @@@
 +/*
 + * 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 static org.junit.Assert.fail;
 +
 +import java.util.Arrays;
 +import java.util.List;
 +import org.apache.syncope.common.lib.SyncopeClientException;
 +import org.apache.syncope.common.lib.to.AccountPolicyTO;
 +import org.apache.syncope.common.lib.to.PasswordPolicyTO;
 +import org.apache.syncope.common.lib.to.SyncPolicyTO;
 +import org.apache.syncope.common.lib.types.AccountPolicySpec;
 +import org.apache.syncope.common.lib.types.AnyTypeKind;
 +import org.apache.syncope.common.lib.types.ClientExceptionType;
 +import org.apache.syncope.common.lib.types.PasswordPolicySpec;
 +import org.apache.syncope.common.lib.types.PolicyType;
 +import org.apache.syncope.common.lib.types.SyncPolicySpec;
 +import org.apache.syncope.common.lib.types.SyncPolicySpecItem;
 +import org.junit.FixMethodOrder;
 +import org.junit.Test;
 +import org.junit.runners.MethodSorters;
 +
 +@FixMethodOrder(MethodSorters.JVM)
 +public class PolicyITCase extends AbstractITCase {
 +
 +    private SyncPolicyTO buildSyncPolicyTO() {
 +        SyncPolicyTO policy = new SyncPolicyTO();
 +
 +        SyncPolicySpecItem item = new SyncPolicySpecItem();
 +        item.setAnyTypeKey(AnyTypeKind.USER.name());
 +        item.setJavaRule(TestSyncRule.class.getName());
 +
 +        SyncPolicySpec spec = new SyncPolicySpec();
 +        spec.getItems().add(item);
 +
 +        policy.setSpecification(spec);
 +        policy.setDescription("Sync policy");
 +
 +        return policy;
 +    }
 +
 +    @Test
 +    public void listByType() {
 +        List<SyncPolicyTO> policyTOs = policyService.list(PolicyType.SYNC);
 +
 +        assertNotNull(policyTOs);
 +        assertFalse(policyTOs.isEmpty());
 +    }
 +
 +    @Test
 +    public void getAccountPolicy() {
 +        AccountPolicyTO policyTO = policyService.read(6L);
 +
 +        assertNotNull(policyTO);
 +        assertTrue(policyTO.getUsedByResources().isEmpty());
 +        assertTrue(policyTO.getUsedByRealms().contains("/odd"));
 +    }
 +
 +    @Test
 +    public void getPasswordPolicy() {
 +        PasswordPolicyTO policyTO = policyService.read(4L);
 +
 +        assertNotNull(policyTO);
 +        assertTrue(policyTO.getUsedByResources().contains(RESOURCE_NAME_NOPROPAGATION));
 +        assertTrue(policyTO.getUsedByRealms().containsAll(Arrays.asList("/", "/odd", "/even")));
 +    }
 +
 +    @Test
 +    public void getSyncPolicy() {
 +        SyncPolicyTO policyTO = policyService.read(1L);
 +
 +        assertNotNull(policyTO);
 +        assertTrue(policyTO.getUsedByRealms().isEmpty());
 +    }
 +
 +    @Test
 +    public void createMissingDescription() {
 +        SyncPolicyTO policy = new SyncPolicyTO();
 +        policy.setSpecification(new SyncPolicySpec());
 +
 +        try {
 +            createPolicy(policy);
 +            fail();
 +        } catch (SyncopeClientException e) {
 +            assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
 +        }
 +    }
 +
 +    @Test
 +    public void create() {
 +        SyncPolicyTO policy = buildSyncPolicyTO();
 +
 +        SyncPolicyTO policyTO = createPolicy(policy);
 +
 +        assertNotNull(policyTO);
 +        assertEquals(PolicyType.SYNC, policyTO.getType());
 +        assertEquals(TestSyncRule.class.getName(),
 +                policyTO.getSpecification().getItem(AnyTypeKind.USER.name()).getJavaRule());
 +    }
 +
 +    @Test
 +    public void update() {
 +        // get global password
 +        PasswordPolicyTO globalPolicy = policyService.read(2L);
 +
 +        PasswordPolicyTO policy = new PasswordPolicyTO();
 +        policy.setDescription("A simple password policy");
 +        policy.setSpecification(globalPolicy.getSpecification());
 +
 +        // create a new password policy using global password as a template
 +        policy = createPolicy(policy);
 +
 +        // read new password policy
 +        policy = policyService.read(policy.getKey());
 +
 +        assertNotNull("find to update did not work", policy);
 +
 +        PasswordPolicySpec policySpec = policy.getSpecification();
 +        policySpec.setMaxLength(22);
 +        policy.setSpecification(policySpec);
 +
 +        // update new password policy
 +        policyService.update(policy);
 +        policy = policyService.read(policy.getKey());
 +
 +        assertNotNull(policy);
 +        assertEquals(PolicyType.PASSWORD, policy.getType());
 +        assertEquals(22, policy.getSpecification().getMaxLength());
 +        assertEquals(8, policy.getSpecification().getMinLength());
 +    }
 +
 +    @Test
 +    public void delete() {
 +        SyncPolicyTO policy = buildSyncPolicyTO();
 +
 +        SyncPolicyTO policyTO = createPolicy(policy);
 +        assertNotNull(policyTO);
 +
 +        policyService.delete(policyTO.getKey());
 +
 +        try {
 +            policyService.read(policyTO.getKey());
 +            fail();
 +        } catch (SyncopeClientException e) {
 +            assertNotNull(e);
 +        }
 +    }
 +
 +    @Test
 +    public void getCorrelationRules() {
 +        assertEquals(1, syncopeService.info().getSyncCorrelationRules().size());
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE553() {
 +        AccountPolicyTO policy = new AccountPolicyTO();
 +        policy.setDescription("SYNCOPE553");
 +
 +        final AccountPolicySpec accountPolicySpec = new AccountPolicySpec();
 +        accountPolicySpec.setMinLength(3);
 +        accountPolicySpec.setMaxLength(8);
 +        policy.setSpecification(accountPolicySpec);
 +
 +        policy = createPolicy(policy);
 +        assertNotNull(policy);
 +    }
++
++    @Test
++    public void issueSYNCOPE682() {
++        AccountPolicyTO policy = new AccountPolicyTO();
++        policy.setDescription("SYNCOPE682");
++        policy.getResources().add(RESOURCE_NAME_LDAP);
++
++        final AccountPolicySpec accountPolicySpec = new AccountPolicySpec();
++        accountPolicySpec.setMinLength(3);
++        accountPolicySpec.setMaxLength(8);
++        policy.setSpecification(accountPolicySpec);
++
++        policy = createPolicy(policy);
++        assertNotNull(policy);
++    }
 +}