[SYNCOPE-666] All but integration tests work
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/705bfb86 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/705bfb86 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/705bfb86 Branch: refs/heads/master Commit: 705bfb86c37a06a538e8973cee8c4948d160bac4 Parents: c608b58 Author: Francesco Chicchiriccò <[email protected]> Authored: Wed May 27 15:06:04 2015 +0200 Committer: Francesco Chicchiriccò <[email protected]> Committed: Wed May 27 15:06:04 2015 +0200 ---------------------------------------------------------------------- .../client/console/rest/SchemaRestClient.java | 1 - .../common/lib/types/ClientExceptionType.java | 4 +- .../syncope/core/logic/AnyObjectLogic.java | 27 +-- .../syncope/core/logic/NotificationTest.java | 3 - .../core/persistence/api/entity/Any.java | 6 + .../persistence/jpa/entity/AbstractAny.java | 92 ++++++++ .../persistence/jpa/entity/AbstractAttr.java | 81 +------ .../persistence/jpa/entity/conf/JPAConf.java | 18 ++ .../api/AnyObjectProvisioningManager.java | 9 - .../api/GroupProvisioningManager.java | 4 - .../provisioning/api/ProvisioningManager.java | 7 + .../api/UserProvisioningManager.java | 2 - .../provisioning/api/data/UserDataBinder.java | 8 + .../api/propagation/PropagationManager.java | 23 +- .../DefaultAnyObjectProvisioningManager.java | 173 +++++++++++++++ .../java/DefaultGroupProvisioningManager.java | 60 +++--- .../java/DefaultUserProvisioningManager.java | 122 ++++++----- .../java/data/AbstractAnyDataBinder.java | 51 ++--- .../java/data/AnyObjectDataBinderImpl.java | 209 +++++++++++++++++++ .../java/data/GroupDataBinderImpl.java | 7 +- .../java/data/ResourceDataBinderImpl.java | 49 +++-- .../java/data/UserDataBinderImpl.java | 21 +- .../propagation/PropagationManagerImpl.java | 77 ++++--- .../java/sync/AbstractProvisioningJob.java | 10 +- .../src/main/resources/provisioning.properties | 1 + .../src/main/resources/provisioningContext.xml | 1 + .../java/data/ResourceDataBinderTest.java | 5 +- .../java/AbstractAnyObjectWorkflowAdapter.java | 61 ++++++ .../java/DefaultAnyObjectWorkflowAdapter.java | 112 ++++++++++ .../src/main/resources/workflow.properties | 1 + .../src/main/resources/workflowContext.xml | 1 + .../camel/CamelGroupProvisioningManager.java | 12 +- .../camel/CamelUserProvisioningManager.java | 11 + .../camel/processor/GroupDeleteProcessor.java | 16 +- 34 files changed, 953 insertions(+), 332 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java index 9f7a6d2..8a145dc 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java @@ -31,7 +31,6 @@ import org.apache.syncope.common.lib.to.AbstractSchemaTO; import org.apache.syncope.common.lib.to.DerSchemaTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; import org.apache.syncope.common.lib.to.VirSchemaTO; -import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.SchemaType; import org.apache.syncope.common.rest.api.service.SchemaService; import org.springframework.stereotype.Component; http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java index 6875279..498f603 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java @@ -37,9 +37,11 @@ public enum ClientExceptionType { InvalidPolicy(Response.Status.BAD_REQUEST), InvalidConf(Response.Status.BAD_REQUEST), InvalidPath(Response.Status.BAD_REQUEST), + InvalidProvision(Response.Status.BAD_REQUEST), InvalidReport(Response.Status.BAD_REQUEST), InvalidReportExec(Response.Status.BAD_REQUEST), - InvalidGroups(Response.Status.BAD_REQUEST), + InvalidAnyObject(Response.Status.BAD_REQUEST), + InvalidGroup(Response.Status.BAD_REQUEST), InvalidSchemaDefinition(Response.Status.BAD_REQUEST), InvalidSearchExpression(Response.Status.BAD_REQUEST), InvalidPageOrSize(Response.Status.BAD_REQUEST), http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java index 31fda37..4919097 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java @@ -37,9 +37,7 @@ import org.apache.syncope.common.lib.to.AnyObjectTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.Entitlement; -import org.apache.syncope.core.misc.RealmUtils; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; -import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager; @@ -136,7 +134,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod> public List<AnyObjectTO> search(final SearchCond searchCondition, final int page, final int size, final List<OrderByClause> orderBy, final List<String> realms) { - final List<AnyObject> matchingAnyObjects = searchDAO.search( + List<AnyObject> matchingAnyObjects = searchDAO.search( getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_SEARCH), realms), searchCondition, page, size, orderBy, AnyTypeKind.ANY_OBJECT); return CollectionUtils.collect(matchingAnyObjects, new Transformer<AnyObject, AnyObjectTO>() { @@ -227,7 +225,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod> @Transactional(rollbackFor = { Throwable.class }) @Override public AnyObjectTO unlink(final Long anyObjectKey, final Collection<String> resources) { - final AnyObjectMod anyObjectMod = new AnyObjectMod(); + AnyObjectMod anyObjectMod = new AnyObjectMod(); anyObjectMod.setKey(anyObjectKey); anyObjectMod.getResourcesToRemove().addAll(resources); final Long updatedResult = provisioningManager.unlink(anyObjectMod); @@ -239,7 +237,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod> @Transactional(rollbackFor = { Throwable.class }) @Override public AnyObjectTO link(final Long anyObjectKey, final Collection<String> resources) { - final AnyObjectMod anyObjectMod = new AnyObjectMod(); + AnyObjectMod anyObjectMod = new AnyObjectMod(); anyObjectMod.setKey(anyObjectKey); anyObjectMod.getResourcesToAdd().addAll(resources); return binder.getAnyObjectTO(provisioningManager.link(anyObjectMod)); @@ -249,7 +247,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod> @Transactional(rollbackFor = { Throwable.class }) @Override public AnyObjectTO unassign(final Long anyObjectKey, final Collection<String> resources) { - final AnyObjectMod anyObjectMod = new AnyObjectMod(); + AnyObjectMod anyObjectMod = new AnyObjectMod(); anyObjectMod.setKey(anyObjectKey); anyObjectMod.getResourcesToRemove().addAll(resources); return update(anyObjectMod); @@ -258,10 +256,10 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod> @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')") @Transactional(rollbackFor = { Throwable.class }) @Override - public AnyObjectTO assign( - final Long anyObjectKey, final Collection<String> resources, final boolean changePwd, final String password) { + public AnyObjectTO assign(final Long anyObjectKey, final Collection<String> resources, + final boolean changePwd, final String password) { - final AnyObjectMod userMod = new AnyObjectMod(); + AnyObjectMod userMod = new AnyObjectMod(); userMod.setKey(anyObjectKey); userMod.getResourcesToAdd().addAll(resources); return update(userMod); @@ -271,7 +269,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod> @Transactional(rollbackFor = { Throwable.class }) @Override public AnyObjectTO deprovision(final Long anyObjectKey, final Collection<String> resources) { - final AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey); + AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey); List<PropagationStatus> statuses = provisioningManager.deprovision(anyObjectKey, resources); @@ -283,8 +281,9 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod> @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')") @Transactional(rollbackFor = { Throwable.class }) @Override - public AnyObjectTO provision( - final Long anyObjectKey, final Collection<String> resources, final boolean changePwd, final String password) { + public AnyObjectTO provision(final Long anyObjectKey, final Collection<String> resources, + final boolean changePwd, final String password) { + AnyObjectTO original = binder.getAnyObjectTO(anyObjectKey); //trick: assign and retrieve propagation statuses ... @@ -297,7 +296,9 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod> } @Override - protected AnyObjectTO resolveReference(final Method method, final Object... args) throws UnresolvedReferenceException { + protected AnyObjectTO resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + Long key = null; if (ArrayUtils.isNotEmpty(args)) { http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java ---------------------------------------------------------------------- diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java index 64aaa09..4401a6b 100644 --- a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java +++ b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java @@ -97,9 +97,6 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class NotificationTest { - /** - * Logger. - */ private static final Logger LOG = LoggerFactory.getLogger(NotificationTest.class); private static final String SMTP_HOST = "localhost"; http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java index 12bf9b6..0384db7 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java @@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.api.entity; import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; import java.util.List; +import java.util.Set; public interface Any<P extends PlainAttr<?>, D extends DerAttr<?>, V extends VirAttr<?>> extends AnnotatedEntity<Long> { @@ -77,4 +78,9 @@ public interface Any<P extends PlainAttr<?>, D extends DerAttr<?>, V extends Vir List<? extends AnyTypeClass> getAuxClasses(); + Set<PlainSchema> getAllowedPlainSchemas(); + + Set<DerSchema> getAllowedDerSchemas(); + + Set<VirSchema> getAllowedVirSchemas(); } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java index 161927c..2e344b0 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java @@ -20,20 +20,33 @@ package org.apache.syncope.core.persistence.jpa.entity; import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.persistence.Column; import javax.persistence.FetchType; import javax.persistence.ManyToOne; import javax.persistence.MappedSuperclass; +import javax.persistence.Transient; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.Predicate; import org.apache.commons.collections4.Transformer; import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.DerAttr; +import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainAttr; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.VirAttr; +import org.apache.syncope.core.persistence.api.entity.VirSchema; +import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; +import org.apache.syncope.core.persistence.api.entity.user.UMembership; +import org.apache.syncope.core.persistence.api.entity.user.User; @MappedSuperclass public abstract class AbstractAny<P extends PlainAttr<?>, D extends DerAttr<?>, V extends VirAttr<?>> @@ -50,6 +63,15 @@ public abstract class AbstractAny<P extends PlainAttr<?>, D extends DerAttr<?>, @Column(nullable = true) private String status; + @Transient + private Set<PlainSchema> allowedPlainSchemas; + + @Transient + private Set<DerSchema> allowedDerSchemas; + + @Transient + private Set<VirSchema> allowedVirSchemas; + @Override public Realm getRealm() { return realm; @@ -146,4 +168,74 @@ public abstract class AbstractAny<P extends PlainAttr<?>, D extends DerAttr<?>, public List<? extends ExternalResource> getResources() { return internalGetResources(); } + + private void populateAllowedSchemas(final Collection<? extends AnyTypeClass> anyTypeClasses) { + for (AnyTypeClass anyTypeClass : anyTypeClasses) { + allowedPlainSchemas.addAll(anyTypeClass.getPlainSchemas()); + } + + for (AnyTypeClass anyTypeClass : anyTypeClasses) { + allowedDerSchemas.addAll(anyTypeClass.getDerSchemas()); + } + + for (AnyTypeClass anyTypeClass : anyTypeClasses) { + allowedVirSchemas.addAll(anyTypeClass.getVirSchemas()); + } + } + + private void populateAllowedSchemas() { + synchronized (this) { + if (allowedPlainSchemas == null) { + allowedPlainSchemas = new HashSet<>(); + } else { + allowedPlainSchemas.clear(); + } + if (allowedDerSchemas == null) { + allowedDerSchemas = new HashSet<>(); + } else { + allowedDerSchemas.clear(); + } + if (allowedVirSchemas == null) { + allowedVirSchemas = new HashSet<>(); + } else { + allowedVirSchemas.clear(); + } + + populateAllowedSchemas(getType().getClasses()); + populateAllowedSchemas(getAuxClasses()); + if (this instanceof User) { + for (UMembership memb : ((User) this).getMemberships()) { + for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) { + populateAllowedSchemas(typeExtension.getAuxClasses()); + } + } + } + if (this instanceof AnyObject) { + for (AMembership memb : ((AnyObject) this).getMemberships()) { + for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) { + populateAllowedSchemas(typeExtension.getAuxClasses()); + } + } + } + } + } + + @Override + public Set<PlainSchema> getAllowedPlainSchemas() { + populateAllowedSchemas(); + return allowedPlainSchemas; + } + + @Override + public Set<DerSchema> getAllowedDerSchemas() { + populateAllowedSchemas(); + return allowedDerSchemas; + } + + @Override + public Set<VirSchema> getAllowedVirSchemas() { + populateAllowedSchemas(); + return allowedVirSchemas; + } + } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java index 4f4a3ec..914bd02 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java @@ -18,84 +18,30 @@ */ package org.apache.syncope.core.persistence.jpa.entity; -import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.Set; -import javax.persistence.Transient; import org.apache.syncope.core.persistence.api.entity.Any; -import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.Attr; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Schema; import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; -import org.apache.syncope.core.persistence.api.entity.user.UMembership; -import org.apache.syncope.core.persistence.api.entity.user.User; public abstract class AbstractAttr<S extends Schema, O extends Any<?, ?, ?>> extends AbstractEntity<Long> implements Attr<S, O> { private static final long serialVersionUID = -7722134717360731874L; - @Transient - private Set<PlainSchema> allowedPlainSchemas; - - @Transient - private Set<DerSchema> allowedDerSchemas; - - @Transient - private Set<VirSchema> allowedVirSchemas; - - private void populateClasses(final Collection<? extends AnyTypeClass> anyTypeClasses) { - synchronized (this) { - if (getSchema() instanceof PlainSchema) { - if (allowedPlainSchemas == null) { - allowedPlainSchemas = new HashSet<>(); - } - for (AnyTypeClass anyTypeClass : anyTypeClasses) { - allowedPlainSchemas.addAll(anyTypeClass.getPlainSchemas()); - } - } else if (getSchema() instanceof DerSchema) { - if (allowedDerSchemas == null) { - allowedDerSchemas = new HashSet<>(); - } - for (AnyTypeClass anyTypeClass : anyTypeClasses) { - allowedDerSchemas.addAll(anyTypeClass.getDerSchemas()); - } - } else if (getSchema() instanceof VirSchema) { - if (allowedVirSchemas == null) { - allowedVirSchemas = new HashSet<>(); - } - for (AnyTypeClass anyTypeClass : anyTypeClasses) { - allowedVirSchemas.addAll(anyTypeClass.getVirSchemas()); - } - } - } - } - @SuppressWarnings("unchecked") - private Set<S> getAllowedSchemas() { + private Set<S> getAllowedSchemas(final O any) { Set<S> result = Collections.emptySet(); if (getSchema() instanceof PlainSchema) { - if (allowedPlainSchemas == null) { - allowedPlainSchemas = new HashSet<>(); - } - result = (Set<S>) allowedPlainSchemas; + result = (Set<S>) any.getAllowedPlainSchemas(); } else if (getSchema() instanceof DerSchema) { - if (allowedDerSchemas == null) { - allowedDerSchemas = new HashSet<>(); - } - result = (Set<S>) allowedDerSchemas; + result = (Set<S>) any.getAllowedDerSchemas(); } else if (getSchema() instanceof VirSchema) { - if (allowedVirSchemas == null) { - allowedVirSchemas = new HashSet<>(); - } - result = (Set<S>) allowedVirSchemas; + result = (Set<S>) any.getAllowedVirSchemas(); } return result; @@ -106,24 +52,7 @@ public abstract class AbstractAttr<S extends Schema, O extends Any<?, ?, ?>> throw new IllegalStateException("First set owner then schema and finally add values"); } - populateClasses(getOwner().getType().getClasses()); - populateClasses(getOwner().getAuxClasses()); - if (getOwner() instanceof User) { - for (UMembership memb : ((User) getOwner()).getMemberships()) { - for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) { - populateClasses(typeExtension.getAuxClasses()); - } - } - } - if (getOwner() instanceof AnyObject) { - for (AMembership memb : ((AnyObject) getOwner()).getMemberships()) { - for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) { - populateClasses(typeExtension.getAuxClasses()); - } - } - } - - if (!getAllowedSchemas().contains(schema)) { + if (!getAllowedSchemas(getOwner()).contains(schema)) { throw new IllegalArgumentException(schema + " not allowed for this instance"); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java index 3253f66..2b44253 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java @@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity.conf; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import javax.persistence.Cacheable; import javax.persistence.CascadeType; import javax.persistence.Entity; @@ -33,8 +34,11 @@ import org.apache.commons.collections4.Predicate; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.DerAttr; +import org.apache.syncope.core.persistence.api.entity.DerSchema; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.VirAttr; +import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr; import org.apache.syncope.core.persistence.api.entity.conf.Conf; import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; @@ -210,4 +214,18 @@ public class JPAConf extends AbstractAnnotatedEntity<Long> implements Conf { // nothing to do } + @Override + public Set<PlainSchema> getAllowedPlainSchemas() { + return Collections.emptySet(); + } + + @Override + public Set<DerSchema> getAllowedDerSchemas() { + return Collections.emptySet(); + } + + @Override + public Set<VirSchema> getAllowedVirSchemas() { + return Collections.emptySet(); + } } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java index 6b423d5..6928ffd 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java @@ -18,17 +18,8 @@ */ package org.apache.syncope.core.provisioning.api; -import java.util.List; -import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.mod.AnyObjectMod; -import org.apache.syncope.common.lib.to.PropagationStatus; import org.apache.syncope.common.lib.to.AnyObjectTO; public interface AnyObjectProvisioningManager extends ProvisioningManager<AnyObjectTO, AnyObjectMod> { - - Pair<Long, List<PropagationStatus>> create(AnyObjectTO anyObjectTO, Set<String> excludedResources); - - Pair<Long, List<PropagationStatus>> update(AnyObjectMod anyObjectMod, Set<String> excludedResources); - } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java index 0913405..1dce013 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java @@ -28,11 +28,7 @@ import org.apache.syncope.common.lib.to.GroupTO; public interface GroupProvisioningManager extends ProvisioningManager<GroupTO, GroupMod> { - Pair<Long, List<PropagationStatus>> create(GroupTO groupTO, Set<String> excludedResources); - Pair<Long, List<PropagationStatus>> create( GroupTO groupTO, Map<Long, String> groupOwnerMap, Set<String> excludedResources); - Pair<Long, List<PropagationStatus>> update(GroupMod groupMod, Set<String> excludedResources); - } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java index 28b2663..e517270 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java @@ -20,6 +20,7 @@ package org.apache.syncope.core.provisioning.api; import java.util.Collection; import java.util.List; +import java.util.Set; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.mod.AnyMod; import org.apache.syncope.common.lib.to.AnyTO; @@ -29,10 +30,16 @@ public interface ProvisioningManager<T extends AnyTO, M extends AnyMod> { Pair<Long, List<PropagationStatus>> create(T anyTO); + Pair<Long, List<PropagationStatus>> create(T anyTO, Set<String> excludedResources); + Pair<Long, List<PropagationStatus>> update(M anyMod); + Pair<Long, List<PropagationStatus>> update(M anyMod, Set<String> excludedResources); + List<PropagationStatus> delete(Long anyKey); + List<PropagationStatus> delete(Long anyKey, Set<String> excludedResources); + Long unlink(M anyMod); Long link(M anyMod); http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java index ad7a01e..810a788 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java @@ -46,8 +46,6 @@ public interface UserProvisioningManager extends ProvisioningManager<UserTO, Use Pair<Long, List<PropagationStatus>> update(UserMod userMod, Long key, ProvisioningResult result, Boolean enabled, Set<String> excludedResources); - List<PropagationStatus> delete(Long key, Set<String> excludedResources); - void requestPasswordReset(Long key); void confirmPasswordReset(User user, String token, String password); http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java index e5fbb00..942c212 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java @@ -35,6 +35,14 @@ public interface UserDataBinder { void create(User user, UserTO userTO, boolean storePassword); + /** + * Update user, given UserMod. + * + * @param toBeUpdated user to be updated + * @param userMod bean containing update request + * @return updated user + propagation by resource + * @see PropagationByResource + */ PropagationByResource update(User toBeUpdated, UserMod userMod); boolean verifyPassword(String username, String password); http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java index 36821c3..cf8cde4 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java @@ -113,13 +113,24 @@ public interface PropagationManager { List<PropagationTask> getGroupDeleteTasks( Long groupKey, Set<String> resourceNames, Collection<String> noPropResourceNames); + List<PropagationTask> getAnyObjectCreateTasks( + WorkflowResult<Long> wfResult, Collection<AttrTO> vAttrs, Collection<String> noPropResourceNames); + List<PropagationTask> getAnyObjectCreateTasks(Long anyObjectKey, Collection<AttrTO> vAttrs, - PropagationByResource propByRes, List<String> noPropResourceNames); + PropagationByResource propByRes, Collection<String> noPropResourceNames); + + List<PropagationTask> getAnyObjectUpdateTasks(WorkflowResult<Long> wfResult, Set<String> vAttrsToBeRemoved, + Set<AttrMod> vAttrsToBeUpdated, Set<String> noPropResourceNames); + + List<PropagationTask> getAnyObjectDeleteTasks(Long anyObjectKey); List<PropagationTask> getAnyObjectDeleteTasks(Long anyObjectKey, String noPropResourceName); List<PropagationTask> getAnyObjectDeleteTasks(Long anyObjectKey, Collection<String> noPropResourceNames); + List<PropagationTask> getAnyObjectDeleteTasks( + Long groupKey, Set<String> resourceNames, Collection<String> noPropResourceNames); + /** * Create the user on every associated resource. * @@ -186,14 +197,4 @@ public interface PropagationManager { List<PropagationTask> getUserDeleteTasks( Long userKey, Set<String> resourceNames, Collection<String> noPropResourceNames); - /** - * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for - * some resources specifying a set of resource names. Exceptions won't be ignored and the process will be stopped if - * the creation fails onto a mandatory resource. - * - * @param wfResult user to be propagated (and info associated), as per result from workflow - * @return list of propagation tasks - */ - List<PropagationTask> getUserDeleteTasks(WorkflowResult<Long> wfResult); - } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java new file mode 100644 index 0000000..1bd2638 --- /dev/null +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java @@ -0,0 +1,173 @@ +/* + * 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.provisioning.java; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.syncope.common.lib.mod.AnyObjectMod; +import org.apache.syncope.common.lib.to.PropagationStatus; +import org.apache.syncope.common.lib.to.AnyObjectTO; +import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; +import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; +import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager; +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.core.provisioning.api.propagation.PropagationException; +import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; +import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; +import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; +import org.apache.syncope.core.misc.spring.ApplicationContextProvider; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisioningManager { + + private static final Logger LOG = LoggerFactory.getLogger(AnyObjectProvisioningManager.class); + + @Autowired + protected AnyObjectWorkflowAdapter awfAdapter; + + @Autowired + protected PropagationManager propagationManager; + + @Autowired + protected PropagationTaskExecutor taskExecutor; + + @Autowired + protected VirAttrHandler virtAttrHandler; + + @Autowired + protected AnyObjectDAO anyObjectDAO; + + @Override + public Pair<Long, List<PropagationStatus>> create(final AnyObjectTO anyObjectTO) { + return create(anyObjectTO, Collections.<String>emptySet()); + } + + @Override + public Pair<Long, List<PropagationStatus>> create( + final AnyObjectTO anyObjectTO, final Set<String> excludedResources) { + + WorkflowResult<Long> created = awfAdapter.create(anyObjectTO); + + List<PropagationTask> tasks = propagationManager.getAnyObjectCreateTasks( + created, anyObjectTO.getVirAttrs(), excludedResources); + PropagationReporter propagationReporter = + ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } + + return new ImmutablePair<>(created.getResult(), propagationReporter.getStatuses()); + } + + @Override + public Pair<Long, List<PropagationStatus>> update(final AnyObjectMod anyObjectMod) { + return update(anyObjectMod, Collections.<String>emptySet()); + } + + @Override + public Pair<Long, List<PropagationStatus>> update( + final AnyObjectMod anyObjectMod, final Set<String> excludedResources) { + + WorkflowResult<Long> updated = awfAdapter.update(anyObjectMod); + + List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(updated, + anyObjectMod.getVirAttrsToRemove(), anyObjectMod.getVirAttrsToUpdate(), null); + PropagationReporter propagationReporter = + ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } + + return new ImmutablePair<>(updated.getResult(), propagationReporter.getStatuses()); + } + + @Override + public List<PropagationStatus> delete(final Long anyObjectKey) { + return delete(anyObjectKey, Collections.<String>emptySet()); + } + + @Override + public List<PropagationStatus> delete(final Long anyObjectKey, final Set<String> excludedResources) { + List<PropagationTask> tasks = new ArrayList<>(); + + AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey); + if (anyObject != null) { + tasks.addAll(propagationManager.getAnyObjectDeleteTasks(anyObject.getKey())); + } + + PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext(). + getBean(PropagationReporter.class); + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } + + awfAdapter.delete(anyObjectKey); + + return propagationReporter.getStatuses(); + } + + @Override + public Long unlink(final AnyObjectMod anyObjectMod) { + return awfAdapter.update(anyObjectMod).getResult(); + } + + @Override + public Long link(final AnyObjectMod anyObjectMod) { + return awfAdapter.update(anyObjectMod).getResult(); + } + + @Override + public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) { + AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey); + + Collection<String> noPropResourceName = CollectionUtils.removeAll(anyObject.getResourceNames(), resources); + + List<PropagationTask> tasks = propagationManager.getAnyObjectDeleteTasks( + anyObjectKey, new HashSet<>(resources), noPropResourceName); + PropagationReporter propagationReporter = + ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } + return propagationReporter.getStatuses(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java index 8535dc2..c7bc1c4 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java @@ -66,16 +66,16 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager protected GroupDAO groupDAO; @Override - public Pair<Long, List<PropagationStatus>> create(final GroupTO any) { - return create(any, Collections.<String>emptySet()); + public Pair<Long, List<PropagationStatus>> create(final GroupTO group) { + return create(group, Collections.<String>emptySet()); } @Override - public Pair<Long, List<PropagationStatus>> create(final GroupTO any, final Set<String> excludedResources) { - WorkflowResult<Long> created = gwfAdapter.create(any); + public Pair<Long, List<PropagationStatus>> create(final GroupTO groupTO, final Set<String> excludedResources) { + WorkflowResult<Long> created = gwfAdapter.create(groupTO); - List<PropagationTask> tasks = - propagationManager.getGroupCreateTasks(created, any.getVirAttrs(), excludedResources); + List<PropagationTask> tasks = propagationManager.getGroupCreateTasks( + created, groupTO.getVirAttrs(), excludedResources); PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().getBean( PropagationReporter.class); try { @@ -107,18 +107,18 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager } @Override - public Pair<Long, List<PropagationStatus>> update(final GroupMod anyMod) { - return update(anyMod, Collections.<String>emptySet()); + public Pair<Long, List<PropagationStatus>> update(final GroupMod groupObjectMod) { + return update(groupObjectMod, Collections.<String>emptySet()); } @Override public Pair<Long, List<PropagationStatus>> update( - final GroupMod anyMod, final Set<String> excludedResources) { + final GroupMod groupMod, final Set<String> excludedResources) { - WorkflowResult<Long> updated = gwfAdapter.update(anyMod); + WorkflowResult<Long> updated = gwfAdapter.update(groupMod); List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(updated, - anyMod.getVirAttrsToRemove(), anyMod.getVirAttrsToUpdate(), null); + groupMod.getVirAttrsToRemove(), groupMod.getVirAttrsToUpdate(), excludedResources); PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); try { @@ -128,25 +128,35 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager propagationReporter.onPrimaryResourceFailure(tasks); } - Pair<Long, List<PropagationStatus>> result = new ImmutablePair<>( - updated.getResult(), propagationReporter.getStatuses()); - return result; + return new ImmutablePair<>(updated.getResult(), propagationReporter.getStatuses()); } @Override - public List<PropagationStatus> delete(final Long anyKey) { - final List<PropagationTask> tasks = new ArrayList<>(); + public List<PropagationStatus> delete(final Long groupObjectKey) { + return delete(groupObjectKey, Collections.<String>emptySet()); + } - Group group = groupDAO.authFind(anyKey); + @Override + public List<PropagationStatus> delete(final Long groupKey, final Set<String> excludedResources) { + List<PropagationTask> tasks = new ArrayList<>(); + + Group group = groupDAO.authFind(groupKey); if (group != null) { // Generate propagation tasks for deleting users from group resources, if they are on those resources only // because of the reason being deleted (see SYNCOPE-357) for (Map.Entry<Long, PropagationByResource> entry + : groupDAO.findUsersWithTransitiveResources(group.getKey()).entrySet()) { + + WorkflowResult<Long> wfResult = + new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet()); + tasks.addAll(propagationManager.getUserDeleteTasks(wfResult.getResult(), excludedResources)); + } + for (Map.Entry<Long, PropagationByResource> entry : groupDAO.findAnyObjectsWithTransitiveResources(group.getKey()).entrySet()) { WorkflowResult<Long> wfResult = new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet()); - tasks.addAll(propagationManager.getUserDeleteTasks(wfResult)); + tasks.addAll(propagationManager.getAnyObjectDeleteTasks(wfResult.getResult(), excludedResources)); } // Generate propagation tasks for deleting this group from resources @@ -162,18 +172,14 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager propagationReporter.onPrimaryResourceFailure(tasks); } - try { - gwfAdapter.delete(anyKey); - } catch (RuntimeException e) { - throw e; - } + gwfAdapter.delete(groupKey); return propagationReporter.getStatuses(); } @Override - public Long unlink(final GroupMod anyMod) { - WorkflowResult<Long> updated = gwfAdapter.update(anyMod); + public Long unlink(final GroupMod groupMod) { + WorkflowResult<Long> updated = gwfAdapter.update(groupMod); return updated.getResult(); } @@ -197,8 +203,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager } @Override - public Long link(final GroupMod anyMod) { - return gwfAdapter.update(anyMod).getResult(); + public Long link(final GroupMod groupMod) { + return gwfAdapter.update(groupMod).getResult(); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java index 58ecb4a..88d3094 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java @@ -77,6 +77,11 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager { } @Override + public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final Set<String> excludedResources) { + return create(userTO, false, false, null, excludedResources); + } + + @Override public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword, final boolean disablePwdPolicyCheck, final Boolean enabled, final Set<String> excludedResources) { @@ -138,6 +143,64 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager { } @Override + public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final Set<String> excludedResources) { + return update(userMod, userMod.getKey(), new ProvisioningResult(), null, excludedResources); + } + + @Override + public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final Long key, + final ProvisioningResult result, final Boolean enabled, final Set<String> excludedResources) { + + WorkflowResult<Pair<UserMod, Boolean>> updated; + try { + updated = uwfAdapter.update(userMod); + } catch (Exception e) { + LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", key, e); + + result.setStatus(ProvisioningResult.Status.FAILURE); + result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage()); + + updated = new WorkflowResult<Pair<UserMod, Boolean>>( + new ImmutablePair<>(userMod, false), new PropagationByResource(), + new HashSet<String>()); + } + + if (enabled != null) { + User user = userDAO.find(key); + + WorkflowResult<Long> enableUpdate = null; + if (user.isSuspended() == null) { + enableUpdate = uwfAdapter.activate(key, null); + } else if (enabled && user.isSuspended()) { + enableUpdate = uwfAdapter.reactivate(key); + } else if (!enabled && !user.isSuspended()) { + enableUpdate = uwfAdapter.suspend(key); + } + + if (enableUpdate != null) { + if (enableUpdate.getPropByRes() != null) { + updated.getPropByRes().merge(enableUpdate.getPropByRes()); + updated.getPropByRes().purge(); + } + updated.getPerformedTasks().addAll(enableUpdate.getPerformedTasks()); + } + } + + List<PropagationTask> tasks = propagationManager.getUserUpdateTasks( + updated, updated.getResult().getKey().getPassword() != null, excludedResources); + PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext(). + getBean(PropagationReporter.class); + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } + + return new ImmutablePair<>(updated.getResult().getKey().getKey(), propagationReporter.getStatuses()); + } + + @Override public List<PropagationStatus> delete(final Long userKey) { return delete(userKey, Collections.<String>emptySet()); } @@ -176,8 +239,8 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager { } @Override - public Long link(final UserMod anyMod) { - return uwfAdapter.update(anyMod).getResult().getKey().getKey(); + public Long link(final UserMod userMod) { + return uwfAdapter.update(userMod).getResult().getKey().getKey(); } @Override @@ -265,61 +328,6 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager { } @Override - public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final Long key, - final ProvisioningResult result, final Boolean enabled, final Set<String> excludedResources) { - - WorkflowResult<Pair<UserMod, Boolean>> updated; - try { - updated = uwfAdapter.update(userMod); - } catch (Exception e) { - LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", key, e); - - result.setStatus(ProvisioningResult.Status.FAILURE); - result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage()); - - updated = new WorkflowResult<Pair<UserMod, Boolean>>( - new ImmutablePair<>(userMod, false), new PropagationByResource(), - new HashSet<String>()); - } - - if (enabled != null) { - User user = userDAO.find(key); - - WorkflowResult<Long> enableUpdate = null; - if (user.isSuspended() == null) { - enableUpdate = uwfAdapter.activate(key, null); - } else if (enabled && user.isSuspended()) { - enableUpdate = uwfAdapter.reactivate(key); - } else if (!enabled && !user.isSuspended()) { - enableUpdate = uwfAdapter.suspend(key); - } - - if (enableUpdate != null) { - if (enableUpdate.getPropByRes() != null) { - updated.getPropByRes().merge(enableUpdate.getPropByRes()); - updated.getPropByRes().purge(); - } - updated.getPerformedTasks().addAll(enableUpdate.getPerformedTasks()); - } - } - - List<PropagationTask> tasks = propagationManager.getUserUpdateTasks( - updated, updated.getResult().getKey().getPassword() != null, excludedResources); - PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext(). - getBean(PropagationReporter.class); - try { - taskExecutor.execute(tasks, propagationReporter); - } catch (PropagationException e) { - LOG.error("Error propagation primary resource", e); - propagationReporter.onPrimaryResourceFailure(tasks); - } - - return new ImmutablePair<>(updated.getResult().getKey().getKey(), - propagationReporter.getStatuses()); - - } - - @Override public void requestPasswordReset(final Long id) { uwfAdapter.requestPasswordReset(id); } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java index f63a9b4..fb01aa4 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java @@ -59,6 +59,7 @@ import org.apache.syncope.core.persistence.api.entity.VirAttr; import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.common.lib.types.PropagationByResource; +import org.apache.syncope.core.misc.ConnObjectUtils; import org.apache.syncope.core.provisioning.java.VirAttrHandler; import org.apache.syncope.core.misc.MappingUtils; import org.apache.syncope.core.misc.jexl.JexlUtils; @@ -130,6 +131,9 @@ abstract class AbstractAnyDataBinder { @Autowired protected VirAttrHandler virtAttrHander; + @Autowired + protected ConnObjectUtils connObjectUtils; + protected void setRealm(final Any<?, ?, ?> any, final AnyMod anyMod) { if (StringUtils.isNotBlank(anyMod.getRealm())) { Realm newRealm = realmDAO.find(anyMod.getRealm()); @@ -239,8 +243,7 @@ abstract class AbstractAnyDataBinder { SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing); // Check if there is some mandatory schema defined for which no value has been provided - List<PlainSchema> plainSchemas = plainSchemaDAO.findAll(); - for (PlainSchema schema : plainSchemas) { + for (PlainSchema schema : any.getAllowedPlainSchemas()) { if (any.getPlainAttr(schema.getKey()) == null && !schema.isReadonly() && (JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), any) @@ -253,8 +256,7 @@ abstract class AbstractAnyDataBinder { } } - List<DerSchema> derSchemas = derSchemaDAO.findAll(); - for (DerSchema derSchema : derSchemas) { + for (DerSchema derSchema : any.getAllowedDerSchemas()) { if (any.getDerAttr(derSchema.getKey()) == null && evaluateMandatoryCondition(anyUtils, any, derSchema.getKey(), anyUtils.derIntMappingType())) { @@ -265,8 +267,7 @@ abstract class AbstractAnyDataBinder { } } - List<VirSchema> virSchemas = virSchemaDAO.findAll(); - for (VirSchema virSchema : virSchemas) { + for (VirSchema virSchema : any.getAllowedVirSchemas()) { if (any.getVirAttr(virSchema.getKey()) == null && !virSchema.isReadonly() && evaluateMandatoryCondition(anyUtils, any, virSchema.getKey(), @@ -294,7 +295,7 @@ abstract class AbstractAnyDataBinder { ExternalResource resource = resourceDAO.find(resourceToBeRemoved); if (resource != null) { propByRes.add(ResourceOperation.DELETE, resource.getKey()); - ((Any<?, ?, ?>) any).remove(resource); + any.remove(resource); } } @@ -305,7 +306,7 @@ abstract class AbstractAnyDataBinder { ExternalResource resource = resourceDAO.find(resourceToBeAdded); if (resource != null) { propByRes.add(ResourceOperation.CREATE, resource.getKey()); - ((Any<?, ?, ?>) any).add(resource); + any.add(resource); } } @@ -512,17 +513,15 @@ abstract class AbstractAnyDataBinder { PlainAttr attr = any.getPlainAttr(schema.getKey()); if (attr == null) { attr = anyUtils.newPlainAttr(); + attr.setOwner(any); attr.setSchema(schema); } - if (attr.getSchema() == null) { - LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO); - } else { - fillAttribute(attributeTO.getValues(), anyUtils, schema, attr, invalidValues); + fillAttribute(attributeTO.getValues(), anyUtils, schema, attr, invalidValues); - if (!attr.getValuesAsStrings().isEmpty()) { - any.add(attr); - attr.setOwner(any); - } + if (attr.getValuesAsStrings().isEmpty()) { + attr.setOwner(null); + } else { + any.add(attr); } } } @@ -538,13 +537,9 @@ abstract class AbstractAnyDataBinder { if (derSchema != null) { DerAttr derAttr = anyUtils.newDerAttr(); + derAttr.setOwner(any); derAttr.setSchema(derSchema); - if (derAttr.getSchema() == null) { - LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO); - } else { - derAttr.setOwner(any); - any.add(derAttr); - } + any.add(derAttr); } } @@ -554,13 +549,9 @@ abstract class AbstractAnyDataBinder { if (virSchema != null) { VirAttr virAttr = anyUtils.newVirAttr(); + virAttr.setOwner(any); virAttr.setSchema(virSchema); - if (virAttr.getSchema() == null) { - LOG.debug("Ignoring {} because no valid schema or template was found", vattrTO); - } else { - virAttr.setOwner(any); - any.add(virAttr); - } + any.add(virAttr); } } @@ -574,13 +565,13 @@ abstract class AbstractAnyDataBinder { "Invalid or null realm specified: " + anyTO.getRealm()); scce.addException(noRealm); } - ((Any<?, ?, ?>) any).setRealm(realm); + any.setRealm(realm); for (String resourceName : anyTO.getResources()) { ExternalResource resource = resourceDAO.find(resourceName); if (resource != null) { - ((Any<?, ?, ?>) any).add(resource); + any.add(resource); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java new file mode 100644 index 0000000..eb7586d --- /dev/null +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java @@ -0,0 +1,209 @@ +/* + * 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.provisioning.java.data; + +import static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.Transformer; +import org.apache.syncope.common.lib.SyncopeClientCompositeException; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.mod.AnyObjectMod; +import org.apache.syncope.common.lib.to.AnyObjectTO; +import org.apache.syncope.common.lib.to.MembershipTO; +import org.apache.syncope.common.lib.types.AnyTypeKind; +import org.apache.syncope.common.lib.types.PropagationByResource; +import org.apache.syncope.common.lib.types.ResourceOperation; +import org.apache.syncope.core.misc.spring.BeanUtils; +import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; +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.provisioning.api.data.AnyObjectDataBinder; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Component +@Transactional(rollbackFor = { Throwable.class }) +public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements AnyObjectDataBinder { + + private static final String[] IGNORE_PROPERTIES = { + "realm", "memberships", "plainAttrs", "derAttrs", "virAttrs", "resources" + }; + + @Transactional(readOnly = true) + @Override + public AnyObjectTO getAnyObjectTO(final Long key) { + return getAnyObjectTO(anyObjectDAO.authFind(key)); + } + + @Override + public AnyObjectTO getAnyObjectTO(final AnyObject anyObject) { + AnyObjectTO anyObjectTO = new AnyObjectTO(); + + BeanUtils.copyProperties(anyObject, anyObjectTO, IGNORE_PROPERTIES); + + connObjectUtils.retrieveVirAttrValues(anyObject); + fillTO(anyObjectTO, anyObject.getRealm().getFullPath(), + anyObject.getPlainAttrs(), anyObject.getDerAttrs(), anyObject.getVirAttrs(), + anyObjectDAO.findAllResources(anyObject)); + + for (AMembership membership : anyObject.getMemberships()) { + MembershipTO membershipTO = new MembershipTO(); + + membershipTO.setKey(membership.getKey()); + membershipTO.setRightKey(membership.getRightEnd().getKey()); + membershipTO.setGroupName(membership.getRightEnd().getName()); + + anyObjectTO.getMemberships().add(membershipTO); + } + + // dynamic memberships + CollectionUtils.collect(anyObjectDAO.findDynGroupMemberships(anyObject), new Transformer<Group, Long>() { + + @Override + public Long transform(final Group group) { + return group.getKey(); + } + }, anyObjectTO.getDynGroups()); + + return anyObjectTO; + } + + @Override + public void create(final AnyObject anyObject, final AnyObjectTO anyObjectTO) { + SyncopeClientCompositeException scce = SyncopeClientException.buildComposite(); + + // memberships + for (MembershipTO membershipTO : anyObjectTO.getMemberships()) { + Group group = groupDAO.find(membershipTO.getRightKey()); + + if (group == null) { + if (LOG.isDebugEnabled()) { + LOG.debug("Ignoring invalid group " + membershipTO.getGroupName()); + } + } else { + AMembership membership = null; + if (anyObject.getKey() != null) { + membership = anyObject.getMembership(group.getKey()); + } + if (membership == null) { + membership = entityFactory.newEntity(AMembership.class); + membership.setRightEnd(group); + membership.setLeftEnd(anyObject); + + anyObject.add(membership); + } + } + } + + // realm, attributes, derived attributes, virtual attributes and resources + fill(anyObject, anyObjectTO, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), scce); + } + + @Override + public PropagationByResource update(final AnyObject toBeUpdated, final AnyObjectMod anyObjectMod) { + // Re-merge any pending change from workflow tasks + final AnyObject anyObject = anyObjectDAO.save(toBeUpdated); + + PropagationByResource propByRes = new PropagationByResource(); + + SyncopeClientCompositeException scce = SyncopeClientException.buildComposite(); + + Collection<String> currentResources = anyObjectDAO.findAllResourceNames(anyObject); + + // fetch connObjectKeys before update + Map<String, String> oldConnObjectKeys = getConnObjectKeys(anyObject); + + // attributes, derived attributes, virtual attributes and resources + propByRes.merge(fill(anyObject, anyObjectMod, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), scce)); + + // store the group ids of membership required to be added + Set<Long> membershipToBeAddedGroupKeys = new HashSet<>(anyObjectMod.getMembershipsToAdd()); + + final Set<String> toBeDeprovisioned = new HashSet<>(); + final Set<String> toBeProvisioned = new HashSet<>(); + + // memberships to be removed + for (Long groupKey : anyObjectMod.getMembershipsToRemove()) { + LOG.debug("Membership to be removed for group {}", groupKey); + + AMembership membership = anyObject.getMembership(groupKey); + if (membership == null) { + LOG.warn("Invalid group key specified for membership to be removed: {}", groupKey); + } else { + if (membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) { + anyObject.remove(membership); + } else { + toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames()); + } + } + } + + // memberships to be added + for (Long groupKey : anyObjectMod.getMembershipsToAdd()) { + LOG.debug("Membership to be added for group {}", groupKey); + + Group group = groupDAO.find(groupKey); + if (group == null) { + LOG.debug("Ignoring invalid group {}", groupKey); + } else { + AMembership membership = anyObject.getMembership(group.getKey()); + if (membership == null) { + membership = entityFactory.newEntity(AMembership.class); + membership.setRightEnd(group); + membership.setLeftEnd(anyObject); + + anyObject.add(membership); + + toBeProvisioned.addAll(group.getResourceNames()); + } + } + } + + propByRes.addAll(ResourceOperation.DELETE, toBeDeprovisioned); + propByRes.addAll(ResourceOperation.UPDATE, toBeProvisioned); + + /** + * In case of new memberships all the current resources have to be updated in order to propagate new group and + * membership attribute values. + */ + if (!toBeDeprovisioned.isEmpty() || !toBeProvisioned.isEmpty()) { + currentResources.removeAll(toBeDeprovisioned); + propByRes.addAll(ResourceOperation.UPDATE, currentResources); + } + + // check if some connObjectKey was changed by the update above + Map<String, String> newcCnnObjectKeys = getConnObjectKeys(anyObject); + for (Map.Entry<String, String> entry : oldConnObjectKeys.entrySet()) { + if (newcCnnObjectKeys.containsKey(entry.getKey()) + && !entry.getValue().equals(newcCnnObjectKeys.get(entry.getKey()))) { + + propByRes.addOldConnObjectKey(entry.getKey(), entry.getValue()); + propByRes.add(ResourceOperation.UPDATE, entry.getKey()); + } + } + + return propByRes; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java index 6bce1b1..a900e70 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java @@ -30,13 +30,11 @@ import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.common.lib.types.PropagationByResource; import org.apache.syncope.core.provisioning.api.data.GroupDataBinder; -import org.apache.syncope.core.misc.ConnObjectUtils; import org.apache.syncope.core.misc.search.SearchCondConverter; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; import org.apache.syncope.core.persistence.api.entity.DynGroupMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -44,9 +42,6 @@ import org.springframework.transaction.annotation.Transactional; @Transactional(rollbackFor = { Throwable.class }) public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupDataBinder { - @Autowired - private ConnObjectUtils connObjectUtils; - private void setDynMembership(final Group group, final AnyTypeKind anyTypeKind, final String dynMembershipFIQL) { SearchCond dynMembershipCond = SearchCondConverter.convert(dynMembershipFIQL); if (!dynMembershipCond.isValid()) { @@ -77,7 +72,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD SyncopeClientCompositeException scce = SyncopeClientException.buildComposite(); // name - SyncopeClientException invalidGroups = SyncopeClientException.build(ClientExceptionType.InvalidGroups); + SyncopeClientException invalidGroups = SyncopeClientException.build(ClientExceptionType.InvalidGroup); if (groupTO.getName() == null) { LOG.error("No name specified for this group"); http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java index 4930764..20b3c58 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java @@ -112,29 +112,34 @@ public class ResourceDataBinderImpl implements ResourceDataBinder { AnyType anyType = anyTypeDAO.find(provisionTO.getAnyType()); if (anyType == null) { LOG.warn("Invalid type specified {}, ignoring...", provisionTO.getAnyType()); - } - - Provision provision = resource.getProvision(anyType); - if (provision == null) { - provision = entityFactory.newEntity(Provision.class); - provision.setResource(resource); - resource.add(provision); - provision.setAnyType(anyType); - } - - provision.setObjectClass(new ObjectClass(provisionTO.getObjectClass())); - - if (provisionTO.getSyncToken() == null) { - provision.setSyncToken(null); - } - - if (provisionTO.getMapping() == null) { - provision.setMapping(null); } else { - Mapping mapping = entityFactory.newEntity(Mapping.class); - mapping.setProvision(provision); - provision.setMapping(mapping); - populateMapping(provisionTO.getMapping(), mapping, entityFactory.newEntity(MappingItem.class)); + Provision provision = resource.getProvision(anyType); + if (provision == null) { + provision = entityFactory.newEntity(Provision.class); + provision.setResource(resource); + resource.add(provision); + provision.setAnyType(anyType); + } + + if (provisionTO.getObjectClass() == null) { + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidProvision); + sce.getElements().add("Null ObjectClass"); + throw sce; + } + provision.setObjectClass(new ObjectClass(provisionTO.getObjectClass())); + + if (provisionTO.getSyncToken() == null) { + provision.setSyncToken(null); + } + + if (provisionTO.getMapping() == null) { + provision.setMapping(null); + } else { + Mapping mapping = entityFactory.newEntity(Mapping.class); + mapping.setProvision(provision); + provision.setMapping(mapping); + populateMapping(provisionTO.getMapping(), mapping, entityFactory.newEntity(MappingItem.class)); + } } } http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java index e20e405..54d10bc 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java @@ -47,7 +47,6 @@ import org.apache.syncope.core.provisioning.api.data.UserDataBinder; import org.apache.syncope.core.misc.security.AuthContextUtils; import org.apache.syncope.core.misc.security.Encryptor; import org.apache.syncope.core.misc.spring.BeanUtils; -import org.apache.syncope.core.misc.ConnObjectUtils; import org.apache.syncope.core.persistence.api.dao.RoleDAO; import org.apache.syncope.core.persistence.api.entity.Role; import org.apache.syncope.core.persistence.api.entity.user.UMembership; @@ -71,9 +70,6 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat private ConfDAO confDAO; @Autowired - private ConnObjectUtils connObjectUtils; - - @Autowired private SecurityQuestionDAO securityQuestionDAO; @Resource(name = "adminUser") @@ -194,14 +190,6 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat user.setSecurityAnswer(userTO.getSecurityAnswer()); } - /** - * Update user, given UserMod. - * - * @param toBeUpdated user to be updated - * @param userMod bean containing update request - * @return updated user + propagation by resource - * @see PropagationByResource - */ @Override public PropagationByResource update(final User toBeUpdated, final UserMod userMod) { // Re-merge any pending change from workflow tasks @@ -292,13 +280,10 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat if (membership == null) { LOG.warn("Invalid group key specified for membership to be removed: {}", groupKey); } else { - if (!membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) { - toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames()); - } - - if (!membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) { - } else { + if (membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) { user.remove(membership); + } else { + toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames()); } } }
