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 2019/10/02 10:45:25 UTC
[syncope] branch 2_1_X updated: [SYNCOPE-957] Push implemented
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/2_1_X by this push:
new bb01007 [SYNCOPE-957] Push implemented
bb01007 is described below
commit bb0100731b8655ceb8e0cab3f9855b6c1a6f2754
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Wed Oct 2 12:36:07 2019 +0200
[SYNCOPE-957] Push implemented
---
.../apache/syncope/common/lib/EntityTOUtils.java | 2 +-
.../syncope/common/lib/to/LinkedAccountTO.java | 23 ++-
.../syncope/core/persistence/api/dao/UserDAO.java | 3 +-
.../persistence/api/entity/user/LinkedAccount.java | 4 +-
.../core/persistence/api/entity/user/User.java | 4 +-
.../persistence/jpa/entity/user/JPAJSONUser.java | 11 +-
.../core/persistence/jpa/dao/JPAUserDAO.java | 25 ++--
.../jpa/entity/user/JPALinkedAccount.java | 12 +-
.../core/persistence/jpa/entity/user/JPAUser.java | 12 +-
.../core/persistence/jpa/outer/UserTest.java | 9 +-
.../provisioning/api/PropagationByResource.java | 2 +-
.../api/propagation/PropagationManager.java | 4 +
.../java/DefaultAnyObjectProvisioningManager.java | 4 +
.../java/DefaultGroupProvisioningManager.java | 36 ++---
.../java/DefaultUserProvisioningManager.java | 11 +-
.../core/provisioning/java/MappingManagerImpl.java | 2 +-
.../provisioning/java/data/UserDataBinderImpl.java | 50 ++++---
.../AbstractPropagationTaskExecutor.java | 61 ++++----
.../java/propagation/DeletingLinkedAccount.java | 16 +--
.../java/propagation/PropagationManagerImpl.java | 10 +-
.../java/pushpull/AbstractPullResultHandler.java | 15 ++
.../java/pushpull/AbstractPushResultHandler.java | 19 +--
.../pushpull/DefaultUserPushResultHandler.java | 93 +++++++++++-
.../core/provisioning/java/pushpull/PushUtils.java | 27 ++++
.../workflow/java/DefaultUserWorkflowAdapter.java | 2 +-
.../camel/component/PropagateEndpoint.java | 2 +-
.../camel/producer/DeleteProducer.java | 6 +-
.../camel/producer/DeprovisionProducer.java | 12 ++
.../camel/producer/ProvisionProducer.java | 14 +-
.../camel/producer/StatusProducer.java | 9 ++
.../camel/producer/UpdateProducer.java | 1 +
.../flowable/impl/FlowableUserWorkflowAdapter.java | 4 +-
.../syncope/fit/buildtools/cxf/UserService.java | 1 +
fit/build-tools/src/main/resources/log4j2.xml | 4 +-
.../org/apache/syncope/fit/AbstractITCase.java | 25 ++++
.../syncope/fit/core/LinkedAccountITCase.java | 156 ++++++++++++++++++---
.../apache/syncope/fit/core/PushTaskITCase.java | 4 +-
.../org/apache/syncope/fit/core/UserITCase.java | 14 +-
.../src/test/resources/rest/CreateScript.groovy | 10 +-
.../src/test/resources/rest/DeleteScript.groovy | 8 +-
.../src/test/resources/rest/SearchScript.groovy | 19 ++-
.../src/test/resources/rest/UpdateScript.groovy | 8 +-
42 files changed, 572 insertions(+), 182 deletions(-)
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java b/common/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java
index ecac7d9..8aeefc0 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java
@@ -52,7 +52,7 @@ public final class EntityTOUtils {
final Collection<LinkedAccountTO> accounts) {
return Collections.unmodifiableMap(accounts.stream().collect(Collectors.toMap(
- account -> Pair.of(account.getResource(), account.getConnObjectName()),
+ account -> Pair.of(account.getResource(), account.getconnObjectKeyValue()),
Function.identity(),
(exist, repl) -> repl)));
}
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/LinkedAccountTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/LinkedAccountTO.java
index ef5210b..967558a 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/LinkedAccountTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/LinkedAccountTO.java
@@ -41,14 +41,9 @@ public class LinkedAccountTO implements Serializable {
private final LinkedAccountTO instance = new LinkedAccountTO();
- public Builder connObjectName(final String connObjectName) {
- instance.setConnObjectName(connObjectName);
- return this;
- }
-
- public Builder resource(final String resource) {
+ public Builder(final String resource, final String connObjectKeyValue) {
instance.setResource(resource);
- return this;
+ instance.setconnObjectKeyValue(connObjectKeyValue);
}
public Builder username(final String username) {
@@ -71,7 +66,7 @@ public class LinkedAccountTO implements Serializable {
}
}
- private String connObjectName;
+ private String connObjectKeyValue;
private String resource;
@@ -85,12 +80,12 @@ public class LinkedAccountTO implements Serializable {
private final Set<String> privileges = new HashSet<>();
- public String getConnObjectName() {
- return connObjectName;
+ public String getconnObjectKeyValue() {
+ return connObjectKeyValue;
}
- public void setConnObjectName(final String connObjectName) {
- this.connObjectName = connObjectName;
+ public void setconnObjectKeyValue(final String connObjectKeyValue) {
+ this.connObjectKeyValue = connObjectKeyValue;
}
public String getResource() {
@@ -147,7 +142,7 @@ public class LinkedAccountTO implements Serializable {
@Override
public int hashCode() {
return new HashCodeBuilder().
- append(connObjectName).
+ append(connObjectKeyValue).
append(resource).
append(username).
append(suspended).
@@ -169,7 +164,7 @@ public class LinkedAccountTO implements Serializable {
}
final LinkedAccountTO other = (LinkedAccountTO) obj;
return new EqualsBuilder().
- append(connObjectName, other.connObjectName).
+ append(connObjectKeyValue, other.connObjectKeyValue).
append(resource, other.resource).
append(username, other.username).
append(suspended, other.suspended).
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
index 5ecd95b..008791e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.persistence.api.dao;
import java.util.Collection;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.core.persistence.api.entity.Privilege;
@@ -61,7 +60,7 @@ public interface UserDAO extends AnyDAO<User> {
Collection<ExternalResource> findAllResources(User user);
- Optional<LinkedAccount> findLinkedAccountByConnObjectName(String connObjectName);
+ boolean linkedAccountExists(String userKey, String connObjectKeyValue);
List<LinkedAccount> findLinkedAccounts(String userKey);
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/LinkedAccount.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/LinkedAccount.java
index 455bf79..0485f05 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/LinkedAccount.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/LinkedAccount.java
@@ -25,9 +25,9 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
public interface LinkedAccount extends Account, Attributable<LAPlainAttr> {
- String getConnObjectName();
+ String getConnObjectKeyValue();
- void setConnObjectName(String connObjectName);
+ void setConnObjectKeyValue(String connObjectKeyValue);
User getOwner();
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
index 9137294..458d415 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
@@ -75,7 +75,9 @@ public interface User extends Account, GroupableRelatable<User, UMembership, UPl
boolean add(LinkedAccount account);
- Optional<? extends LinkedAccount> getLinkedAccount(String resource, String connObjectName);
+ Optional<? extends LinkedAccount> getLinkedAccount(String resource, String connObjectKeyValue);
+
+ List<? extends LinkedAccount> getLinkedAccounts(String resource);
List<? extends LinkedAccount> getLinkedAccounts();
}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUser.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUser.java
index ab346dc..87e2ca2 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUser.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUser.java
@@ -133,14 +133,21 @@ public class JPAJSONUser extends JPAUser implements JSONAttributable<User>, User
}
@Override
- public Optional<? extends LinkedAccount> getLinkedAccount(final String resource, final String connObjectName) {
+ public Optional<? extends LinkedAccount> getLinkedAccount(final String resource, final String connObjectKeyValue) {
return linkedAccounts.stream().
filter(account -> account.getResource().getKey().equals(resource)
- && account.getConnObjectName().equals(connObjectName)).
+ && account.getConnObjectKeyValue().equals(connObjectKeyValue)).
findFirst();
}
@Override
+ public List<? extends LinkedAccount> getLinkedAccounts(final String resource) {
+ return linkedAccounts.stream().
+ filter(account -> account.getResource().getKey().equals(resource)).
+ collect(Collectors.toList());
+ }
+
+ @Override
public List<? extends LinkedAccount> getLinkedAccounts() {
return linkedAccounts;
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index f4f1d05..07ee141 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -25,7 +25,6 @@ import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -545,6 +544,17 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
@Transactional(readOnly = true)
@Override
+ public boolean linkedAccountExists(final String userKey, final String connObjectKeyValue) {
+ Query query = entityManager().createNativeQuery(
+ "SELECT id FROM " + JPALinkedAccount.TABLE + " WHERE owner_id=? AND connObjectKeyValue=?");
+ query.setParameter(1, userKey);
+ query.setParameter(2, connObjectKeyValue);
+
+ return !query.getResultList().isEmpty();
+ }
+
+ @Transactional(readOnly = true)
+ @Override
public List<LinkedAccount> findLinkedAccounts(final String userKey) {
TypedQuery<LinkedAccount> query = entityManager().createQuery(
"SELECT e FROM " + JPALinkedAccount.class.getSimpleName() + " e "
@@ -563,19 +573,6 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
}
@Override
- public Optional<LinkedAccount> findLinkedAccountByConnObjectName(final String connObjectName) {
- TypedQuery<LinkedAccount> query = entityManager().createQuery(
- "SELECT e FROM " + JPALinkedAccount.class.getSimpleName() + " e "
- + "WHERE e.connObjectName=:connObjectName", LinkedAccount.class);
- query.setParameter("connObjectName", connObjectName);
-
- List<LinkedAccount> result = query.getResultList();
- return result.isEmpty()
- ? Optional.empty()
- : Optional.of(result.get(0));
- }
-
- @Override
public List<LinkedAccount> findLinkedAccountsByResource(final ExternalResource resource) {
TypedQuery<LinkedAccount> query = entityManager().createQuery(
"SELECT e FROM " + JPALinkedAccount.class.getSimpleName() + " e "
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java
index c24a85c..dbd47e8 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java
@@ -51,7 +51,7 @@ import org.apache.syncope.core.spring.security.Encryptor;
@Entity
@Table(name = JPALinkedAccount.TABLE, uniqueConstraints =
- @UniqueConstraint(columnNames = { "connObjectName", "resource_id" }))
+ @UniqueConstraint(columnNames = { "connObjectKeyValue", "resource_id" }))
public class JPALinkedAccount extends AbstractGeneratedKeyEntity implements LinkedAccount {
private static final long serialVersionUID = -5141654998687601522L;
@@ -61,7 +61,7 @@ public class JPALinkedAccount extends AbstractGeneratedKeyEntity implements Link
private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
@NotNull
- private String connObjectName;
+ private String connObjectKeyValue;
@ManyToOne(fetch = FetchType.EAGER)
private JPAUser owner;
@@ -94,13 +94,13 @@ public class JPALinkedAccount extends AbstractGeneratedKeyEntity implements Link
private Set<JPAPrivilege> privileges = new HashSet<>();
@Override
- public String getConnObjectName() {
- return connObjectName;
+ public String getConnObjectKeyValue() {
+ return connObjectKeyValue;
}
@Override
- public void setConnObjectName(final String connObjectName) {
- this.connObjectName = connObjectName;
+ public void setConnObjectKeyValue(final String connObjectKeyValue) {
+ this.connObjectKeyValue = connObjectKeyValue;
}
@Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index 651d6f6..abcccac 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -23,6 +23,7 @@ import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Optional;
+import java.util.stream.Collectors;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
@@ -483,14 +484,21 @@ public class JPAUser
}
@Override
- public Optional<? extends LinkedAccount> getLinkedAccount(final String resource, final String connObjectName) {
+ public Optional<? extends LinkedAccount> getLinkedAccount(final String resource, final String connObjectKeyValue) {
return linkedAccounts.stream().
filter(account -> account.getResource().getKey().equals(resource)
- && account.getConnObjectName().equals(connObjectName)).
+ && account.getConnObjectKeyValue().equals(connObjectKeyValue)).
findFirst();
}
@Override
+ public List<? extends LinkedAccount> getLinkedAccounts(final String resource) {
+ return linkedAccounts.stream().
+ filter(account -> account.getResource().getKey().equals(resource)).
+ collect(Collectors.toList());
+ }
+
+ @Override
public List<? extends LinkedAccount> getLinkedAccounts() {
return linkedAccounts;
}
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
index ccf52b4..e7196f6 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
@@ -28,7 +28,6 @@ import static org.junit.jupiter.api.Assertions.fail;
import java.util.Date;
import java.util.List;
import java.util.Objects;
-import java.util.Optional;
import java.util.UUID;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
@@ -232,7 +231,7 @@ public class UserTest extends AbstractTest {
assertTrue(user.getPlainAttrs("obscure").stream().anyMatch(plainAttr -> newM.equals(plainAttr.getMembership())));
}
- private LinkedAccount newLinkedAccount(final String connObjectName) {
+ private LinkedAccount newLinkedAccount(final String connObjectKeyValue) {
User user = userDAO.findByUsername("vivaldi");
user.getLinkedAccounts().stream().filter(Objects::nonNull).forEach(account -> account.setOwner(null));
user.getLinkedAccounts().clear();
@@ -241,7 +240,7 @@ public class UserTest extends AbstractTest {
account.setOwner(user);
user.add(account);
- account.setConnObjectName(connObjectName);
+ account.setConnObjectKeyValue(connObjectKeyValue);
account.setResource(resourceDAO.find("resource-ldap"));
account.add(applicationDAO.findPrivilege("getMighty"));
@@ -272,9 +271,7 @@ public class UserTest extends AbstractTest {
assertTrue(account.getPlainAttr("obscure").isPresent());
assertEquals(account.getOwner(), account.getPlainAttr("obscure").get().getOwner());
- Optional<LinkedAccount> found = userDAO.findLinkedAccountByConnObjectName(account.getConnObjectName());
- assertTrue(found.isPresent());
- assertEquals(account, found.get());
+ assertTrue(userDAO.linkedAccountExists(account.getOwner().getKey(), account.getConnObjectKeyValue()));
List<LinkedAccount> accounts = userDAO.findLinkedAccountsByResource(resourceDAO.find("resource-ldap"));
assertEquals(1, accounts.size());
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/PropagationByResource.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/PropagationByResource.java
index bc1f796..5f82ef3 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/PropagationByResource.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/PropagationByResource.java
@@ -31,7 +31,7 @@ import org.apache.syncope.common.lib.types.ResourceOperation;
/**
* Encapsulates operations to be performed on various resources.
*
- * @param <T> key for propagation: could be simple resource or pair (resource, connObjectName) for linked accounts
+ * @param <T> key for propagation: could be simple resource or pair (resource, connObjectKeyValue) for linked accounts
*/
public class PropagationByResource<T extends Serializable> implements Serializable {
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 a083b66..0378950 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
@@ -78,6 +78,7 @@ public interface PropagationManager {
* @param changePwd whether password should be included for propagation attributes or not
* @param enable whether any object should be enabled or not, may be null to leave unchanged
* @param propByRes operation to be performed per resource
+ * @param propByLinkedAccount operation to be performed for linked accounts
* @param vAttrs virtual attributes to be set
* @param noPropResourceKeys external resource keys not to be considered for propagation
* @return list of propagation tasks
@@ -88,6 +89,7 @@ public interface PropagationManager {
boolean changePwd,
Boolean enable,
PropagationByResource<String> propByRes,
+ PropagationByResource<Pair<String, String>> propByLinkedAccount,
Collection<AttrTO> vAttrs,
Collection<String> noPropResourceKeys);
@@ -119,6 +121,7 @@ public interface PropagationManager {
* @param kind any object type kind
* @param key any object key
* @param propByRes operation to be performed per resource
+ * @param propByLinkedAccount operation to be performed for linked accounts
* @param noPropResourceKeys external resource keys not to be considered for propagation
* @return list of propagation tasks
*/
@@ -126,6 +129,7 @@ public interface PropagationManager {
AnyTypeKind kind,
String key,
PropagationByResource<String> propByRes,
+ PropagationByResource<Pair<String, String>> propByLinkedAccount,
Collection<String> noPropResourceKeys);
/**
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
index 2866183..171fc88 100644
--- 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
@@ -107,6 +107,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
false,
null,
updated.getPropByRes(),
+ null,
anyObjectPatch.getVirAttrs(),
excludedResources);
PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
@@ -136,6 +137,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
AnyTypeKind.ANY_OBJECT,
key,
propByRes,
+ null,
excludedResources);
PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
@@ -172,6 +174,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
null,
propByRes,
null,
+ null,
null);
PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
@@ -189,6 +192,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
AnyTypeKind.ANY_OBJECT,
key,
propByRes,
+ null,
anyObjectDAO.findAllResourceKeys(key).stream().
filter(resource -> !resources.contains(resource)).
collect(Collectors.toList()));
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 87c8789..bf93ee1 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
@@ -129,6 +129,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
false,
null,
updated.getPropByRes(),
+ null,
groupPatch.getVirAttrs(),
excludedResources);
PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync);
@@ -150,28 +151,29 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
// Generate propagation tasks for deleting users and any objects from group resources,
// if they are on those resources only because of the reason being deleted (see SYNCOPE-357)
- groupDataBinder.findUsersWithTransitiveResources(key).entrySet().
- forEach(entry -> {
- taskInfos.addAll(propagationManager.getDeleteTasks(
- AnyTypeKind.USER,
- entry.getKey(),
- entry.getValue(),
- excludedResources));
- });
- groupDataBinder.findAnyObjectsWithTransitiveResources(key).entrySet().
- forEach(entry -> {
- taskInfos.addAll(propagationManager.getDeleteTasks(
- AnyTypeKind.ANY_OBJECT,
- entry.getKey(),
- entry.getValue(),
- excludedResources));
- });
+ groupDataBinder.findUsersWithTransitiveResources(key).forEach((anyKey, propByRes) -> {
+ taskInfos.addAll(propagationManager.getDeleteTasks(
+ AnyTypeKind.USER,
+ anyKey,
+ propByRes,
+ null,
+ excludedResources));
+ });
+ groupDataBinder.findAnyObjectsWithTransitiveResources(key).forEach((anyKey, propByRes) -> {
+ taskInfos.addAll(propagationManager.getDeleteTasks(
+ AnyTypeKind.ANY_OBJECT,
+ anyKey,
+ propByRes,
+ null,
+ excludedResources));
+ });
// Generate propagation tasks for deleting this group from resources
taskInfos.addAll(propagationManager.getDeleteTasks(
AnyTypeKind.GROUP,
key,
null,
+ null,
null));
PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
@@ -200,6 +202,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
null,
propByRes,
null,
+ null,
null);
PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
@@ -217,6 +220,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
AnyTypeKind.GROUP,
key,
propByRes,
+ null,
groupDAO.findAllResourceKeys(key).stream().
filter(resource -> !resources.contains(resource)).
collect(Collectors.toList()));
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 c964321..46e4b9b 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
@@ -198,7 +198,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
userDAO.findLinkedAccounts(key).forEach(account -> propByLinkedAccount.add(
ResourceOperation.DELETE,
- Pair.of(account.getResource().getKey(), account.getConnObjectName())));
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
// Note here that we can only notify about "delete", not any other
// task defined in workflow process definition: this because this
@@ -280,6 +280,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
statusPatch.getType() != StatusPatchType.SUSPEND,
propByRes,
null,
+ null,
null);
PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync);
@@ -345,10 +346,18 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
PropagationByResource<String> propByRes = new PropagationByResource<>();
propByRes.set(ResourceOperation.DELETE, resources);
+ PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
+ userDAO.findLinkedAccounts(key).stream().
+ filter(account -> resources.contains(account.getResource().getKey())).
+ forEach(account -> propByLinkedAccount.add(
+ ResourceOperation.DELETE,
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
+
List<PropagationTaskInfo> taskInfos = propagationManager.getDeleteTasks(
AnyTypeKind.USER,
key,
propByRes,
+ propByLinkedAccount,
userDAO.findAllResourceKeys(key).stream().
filter(resource -> !resources.contains(resource)).
collect(Collectors.toList()));
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
index ae90118..29d5461 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
@@ -292,7 +292,7 @@ public class MappingManagerImpl implements MappingManager {
}
}
- String connObjectKey = account.getConnObjectName();
+ String connObjectKey = account.getConnObjectKeyValue();
MappingUtils.getConnObjectKeyItem(provision).ifPresent(connObjectKeyItem -> {
Attribute connObjectKeyExtAttr = AttributeUtil.find(connObjectKeyItem.getExtAttrName(), attributes);
if (connObjectKeyExtAttr != null) {
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 6342a80..bc02905 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
@@ -25,7 +25,9 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
+import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.BooleanUtils;
@@ -161,12 +163,25 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
if (resource == null) {
LOG.debug("Ignoring invalid resource {}", accountTO.getResource());
} else {
- LinkedAccount account = entityFactory.newEntity(LinkedAccount.class);
- account.setOwner(user);
- user.add(account);
+ Optional<? extends LinkedAccount> found =
+ user.getLinkedAccount(resource.getKey(), accountTO.getconnObjectKeyValue());
+ LinkedAccount account = found.isPresent()
+ ? found.get()
+ : new Supplier<LinkedAccount>() {
+
+ @Override
+ public LinkedAccount get() {
+ LinkedAccount acct = entityFactory.newEntity(LinkedAccount.class);
+ acct.setOwner(user);
+ user.add(acct);
+
+ acct.setConnObjectKeyValue(accountTO.getconnObjectKeyValue());
+ acct.setResource(resource);
+
+ return acct;
+ }
+ }.get();
- account.setConnObjectName(accountTO.getConnObjectName());
- account.setResource(resource);
account.setUsername(accountTO.getUsername());
if (StringUtils.isNotBlank(accountTO.getPassword())) {
account.setPassword(accountTO.getPassword(), CipherAlgorithm.AES);
@@ -577,10 +592,17 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
userPatch.getLinkedAccounts().stream().filter(patch -> patch.getLinkedAccountTO() != null).forEach(patch -> {
user.getLinkedAccount(
patch.getLinkedAccountTO().getResource(),
- patch.getLinkedAccountTO().getConnObjectName()).ifPresent(account -> {
+ patch.getLinkedAccountTO().getconnObjectKeyValue()).ifPresent(account -> {
+
+ if (patch.getOperation() == PatchOperation.DELETE) {
+ user.getLinkedAccounts().remove(account);
+ account.setOwner(null);
+
+ propByLinkedAccount.add(
+ ResourceOperation.DELETE,
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue()));
+ }
- user.getLinkedAccounts().remove(account);
- account.setOwner(null);
account.getPlainAttrs().stream().collect(Collectors.toSet()).forEach(attr -> {
account.remove(attr);
attr.setOwner(null);
@@ -589,11 +611,6 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
plainAttrDAO.delete(attr);
});
- if (patch.getOperation() == PatchOperation.DELETE) {
- propByLinkedAccount.add(
- ResourceOperation.DELETE,
- Pair.of(account.getResource().getKey(), account.getConnObjectName()));
- }
});
if (patch.getOperation() == PatchOperation.ADD_REPLACE) {
linkedAccount(
@@ -606,7 +623,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
user.getLinkedAccounts().forEach(account -> {
propByLinkedAccount.add(
ResourceOperation.CREATE,
- Pair.of(account.getResource().getKey(), account.getConnObjectName()));
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue()));
});
// finalize resource management
@@ -748,9 +765,8 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
// linked accounts
userTO.getLinkedAccounts().addAll(
user.getLinkedAccounts().stream().map(account -> {
- LinkedAccountTO accountTO = new LinkedAccountTO.Builder().
- resource(account.getResource().getKey()).
- connObjectName(account.getConnObjectName()).
+ LinkedAccountTO accountTO = new LinkedAccountTO.Builder(
+ account.getResource().getKey(), account.getConnObjectKeyValue()).
username(account.getUsername()).
password(user.getPassword()).
suspended(BooleanUtils.isTrue(account.isSuspended())).
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index bb5f17c..172f35f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -33,6 +33,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.collections.IteratorChain;
import org.apache.syncope.common.lib.to.ExecTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.common.lib.types.AuditElements.Result;
import org.apache.syncope.common.lib.types.ExecStatus;
@@ -632,37 +633,45 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
? task.getConnObjectKey()
: task.getOldConnObjectKey();
- Set<MappingItem> linkingMappingItems = virSchemaDAO.findByProvision(provision).stream().
- map(schema -> schema.asLinkingMappingItem()).collect(Collectors.toSet());
+ boolean isLinkedAccount = task.getAnyTypeKind() == AnyTypeKind.USER
+ && userDAO.linkedAccountExists(task.getEntityKey(), connObjectKey);
+
+ Set<MappingItem> linkingMappingItems = isLinkedAccount
+ ? Collections.emptySet()
+ : virSchemaDAO.findByProvision(provision).stream().
+ map(schema -> schema.asLinkingMappingItem()).collect(Collectors.toSet());
ConnectorObject obj = null;
+
Optional<? extends MappingItem> connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
- if (connObjectKeyItem.isPresent()) {
- try {
- obj = connector.getObject(
- new ObjectClass(task.getObjectClassName()),
- AttributeBuilder.build(connObjectKeyItem.get().getExtAttrName(), connObjectKey),
- provision.isIgnoreCaseMatch(),
- MappingUtils.buildOperationOptions(new IteratorChain<>(
- MappingUtils.getPropagationItems(provision.getMapping().getItems()).iterator(),
- linkingMappingItems.iterator())));
-
- for (MappingItem item : linkingMappingItems) {
- Attribute attr = obj.getAttributeByName(item.getExtAttrName());
- if (attr == null) {
- virAttrCache.expire(task.getAnyType(), task.getEntityKey(), item.getIntAttrName());
- } else {
- VirAttrCacheValue cacheValue = new VirAttrCacheValue();
- cacheValue.setValues(attr.getValue());
- virAttrCache.put(task.getAnyType(), task.getEntityKey(), item.getIntAttrName(), cacheValue);
- }
+ String connObjectKeyName = connObjectKeyItem.isPresent()
+ ? connObjectKeyItem.get().getExtAttrName()
+ : Name.NAME;
+
+ try {
+ obj = connector.getObject(
+ new ObjectClass(task.getObjectClassName()),
+ AttributeBuilder.build(connObjectKeyName, connObjectKey),
+ provision.isIgnoreCaseMatch(),
+ MappingUtils.buildOperationOptions(new IteratorChain<>(
+ MappingUtils.getPropagationItems(provision.getMapping().getItems()).iterator(),
+ linkingMappingItems.iterator())));
+
+ for (MappingItem item : linkingMappingItems) {
+ Attribute attr = obj.getAttributeByName(item.getExtAttrName());
+ if (attr == null) {
+ virAttrCache.expire(task.getAnyType(), task.getEntityKey(), item.getIntAttrName());
+ } else {
+ VirAttrCacheValue cacheValue = new VirAttrCacheValue();
+ cacheValue.setValues(attr.getValue());
+ virAttrCache.put(task.getAnyType(), task.getEntityKey(), item.getIntAttrName(), cacheValue);
}
- } catch (TimeoutException toe) {
- LOG.debug("Request timeout", toe);
- throw toe;
- } catch (RuntimeException ignore) {
- LOG.debug("While resolving {}", connObjectKey, ignore);
}
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ } catch (RuntimeException ignore) {
+ LOG.debug("While resolving {}", connObjectKey, ignore);
}
return obj;
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DeletingLinkedAccount.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DeletingLinkedAccount.java
index 331aa84..c96eebc 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DeletingLinkedAccount.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DeletingLinkedAccount.java
@@ -39,12 +39,12 @@ public class DeletingLinkedAccount implements LinkedAccount {
private final ExternalResource resource;
- private final String connObjectName;
+ private final String connObjectKeyValue;
- public DeletingLinkedAccount(final User user, final ExternalResource resource, final String connObjectName) {
+ public DeletingLinkedAccount(final User user, final ExternalResource resource, final String connObjectKeyValue) {
this.user = user;
this.resource = resource;
- this.connObjectName = connObjectName;
+ this.connObjectKeyValue = connObjectKeyValue;
}
@Override
@@ -53,12 +53,12 @@ public class DeletingLinkedAccount implements LinkedAccount {
}
@Override
- public String getConnObjectName() {
- return connObjectName;
+ public String getConnObjectKeyValue() {
+ return connObjectKeyValue;
}
@Override
- public void setConnObjectName(final String connObjectName) {
+ public void setConnObjectKeyValue(final String connObjectKeyValue) {
// unsupported
}
@@ -162,7 +162,7 @@ public class DeletingLinkedAccount implements LinkedAccount {
return new HashCodeBuilder().
append(user.getKey()).
append(resource).
- append(connObjectName).
+ append(connObjectKeyValue).
build();
}
@@ -181,7 +181,7 @@ public class DeletingLinkedAccount implements LinkedAccount {
return new EqualsBuilder().
append(user.getKey(), other.user.getKey()).
append(resource, other.resource).
- append(connObjectName, other.connObjectName).
+ append(connObjectKeyValue, other.connObjectKeyValue).
build();
}
}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index f519640..55fb711 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -203,6 +203,7 @@ public class PropagationManagerImpl implements PropagationManager {
final boolean changePwd,
final Boolean enable,
final PropagationByResource<String> propByRes,
+ final PropagationByResource<Pair<String, String>> propByLinkedAccount,
final Collection<AttrTO> vAttrs,
final Collection<String> noPropResourceKeys) {
@@ -212,7 +213,7 @@ public class PropagationManagerImpl implements PropagationManager {
changePwd,
enable,
propByRes,
- null,
+ propByLinkedAccount,
vAttrs,
noPropResourceKeys);
}
@@ -319,9 +320,10 @@ public class PropagationManagerImpl implements PropagationManager {
final AnyTypeKind kind,
final String key,
final PropagationByResource<String> propByRes,
+ final PropagationByResource<Pair<String, String>> propByLinkedAccount,
final Collection<String> noPropResourceKeys) {
- return getDeleteTasks(dao(kind).authFind(key), propByRes, null, noPropResourceKeys);
+ return getDeleteTasks(dao(kind).authFind(key), propByRes, propByLinkedAccount, noPropResourceKeys);
}
@Override
@@ -544,12 +546,12 @@ public class PropagationManagerImpl implements PropagationManager {
provision,
deleteOnResource,
mappingItems,
- Pair.of(account.getConnObjectName(),
+ Pair.of(account.getConnObjectKeyValue(),
mappingManager.prepareAttrs(user, account, password, changePwd, provision)));
tasks.add(accountTask);
LOG.debug("PropagationTask created for Linked Account {}: {}",
- account.getConnObjectName(), accountTask);
+ account.getConnObjectKeyValue(), accountTask);
}
});
}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
index 356d6fc..997e7f4 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -23,10 +23,12 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.AnyOperations;
import org.apache.syncope.common.lib.patch.AnyPatch;
import org.apache.syncope.common.lib.patch.StringPatchItem;
import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.common.lib.types.AuditElements.Result;
import org.apache.syncope.common.lib.types.MatchingRule;
@@ -37,6 +39,7 @@ import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.common.lib.types.UnmatchingRule;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.RemediationDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
@@ -82,6 +85,9 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
protected ConnObjectUtils connObjectUtils;
@Autowired
+ protected UserDAO userDAO;
+
+ @Autowired
protected RemediationDAO remediationDAO;
@Autowired
@@ -474,10 +480,19 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
PropagationByResource<String> propByRes = new PropagationByResource<>();
propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+
+ PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
+ if (getAnyUtils().anyTypeKind() == AnyTypeKind.USER) {
+ userDAO.findLinkedAccounts(key).forEach(account -> propByLinkedAccount.add(
+ ResourceOperation.DELETE,
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
+ }
+
taskExecutor.execute(propagationManager.getDeleteTasks(
provision.getAnyType().getKind(),
key,
propByRes,
+ propByLinkedAccount,
null),
false);
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
index d6829c8..e835c0e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
+import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.syncope.common.lib.patch.AnyPatch;
import org.apache.syncope.common.lib.patch.StringPatchItem;
@@ -118,6 +119,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
enable,
propByRes,
null,
+ null,
noPropResources);
if (!taskInfos.isEmpty()) {
taskInfos.get(0).setBeforeObj(Optional.of(beforeObj));
@@ -141,6 +143,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
any.getType().getKind(),
any.getKey(),
propByRes,
+ null,
noPropResources);
if (!taskInfos.isEmpty()) {
taskInfos.get(0).setBeforeObj(Optional.of(beforeObj));
@@ -281,15 +284,6 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
ConnectorObject beforeObj = connObjs.isEmpty() ? null : connObjs.get(0);
- Object output = null;
- Result resultStatus = null;
-
- Boolean enable = any instanceof User && profile.getTask().isSyncStatus()
- ? ((User) any).isSuspended()
- ? Boolean.FALSE
- : Boolean.TRUE
- : null;
-
if (profile.isDryRun()) {
if (beforeObj == null) {
result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
@@ -313,6 +307,13 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
any.getType().getKind().name().toLowerCase(),
profile.getTask().getResource().getKey(),
operation);
+
+ Object output = null;
+ Result resultStatus = null;
+
+ Boolean enable = any instanceof User && profile.getTask().isSyncStatus()
+ ? BooleanUtils.negate(((User) any).isSuspended())
+ : null;
try {
if (beforeObj == null) {
result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
index d1181d0..f7a4547 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
@@ -20,6 +20,8 @@ package org.apache.syncope.core.provisioning.java.pushpull;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.patch.AnyPatch;
import org.apache.syncope.common.lib.patch.UserPatch;
@@ -29,11 +31,15 @@ import org.apache.syncope.core.provisioning.api.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.Entity;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo;
import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
+import org.apache.syncope.core.provisioning.java.propagation.DefaultPropagationReporter;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
public class DefaultUserPushResultHandler extends AbstractPushResultHandler implements UserPushResultHandler {
@@ -43,6 +49,16 @@ public class DefaultUserPushResultHandler extends AbstractPushResultHandler impl
}
@Override
+ protected String getName(final Any<?> any) {
+ return User.class.cast(any).getUsername();
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return userDataBinder.getUserTO(key);
+ }
+
+ @Override
protected void provision(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
AnyTO before = getAnyTO(any.getKey());
@@ -52,12 +68,18 @@ public class DefaultUserPushResultHandler extends AbstractPushResultHandler impl
PropagationByResource<String> propByRes = new PropagationByResource<>();
propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+ PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
+ ((User) any).getLinkedAccounts(profile.getTask().getResource().getKey()).
+ forEach(account -> propByLinkedAccount.add(
+ ResourceOperation.CREATE,
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
+
PropagationReporter reporter = taskExecutor.execute(propagationManager.getUserCreateTasks(
before.getKey(),
null,
enabled,
propByRes,
- new PropagationByResource<>(),
+ propByLinkedAccount,
before.getVirAttrs(),
noPropResources),
false);
@@ -65,13 +87,74 @@ public class DefaultUserPushResultHandler extends AbstractPushResultHandler impl
}
@Override
- protected String getName(final Any<?> any) {
- return User.class.cast(any).getUsername();
+ protected void update(
+ final Any<?> any,
+ final Boolean enable,
+ final ConnectorObject beforeObj,
+ final ProvisioningReport result) {
+
+ List<String> ownedResources = getAnyUtils().getAllResources(any).stream().
+ map(Entity::getKey).collect(Collectors.toList());
+
+ List<String> noPropResources = new ArrayList<>(ownedResources);
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource<String> propByRes = new PropagationByResource<>();
+ propByRes.add(ResourceOperation.UPDATE, profile.getTask().getResource().getKey());
+ propByRes.addOldConnObjectKey(profile.getTask().getResource().getKey(), beforeObj.getUid().getUidValue());
+
+ PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
+ ((User) any).getLinkedAccounts(profile.getTask().getResource().getKey()).
+ forEach(account -> propByLinkedAccount.add(
+ ResourceOperation.UPDATE,
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
+
+ List<PropagationTaskInfo> taskInfos = propagationManager.getUpdateTasks(
+ any.getType().getKind(),
+ any.getKey(),
+ true,
+ enable,
+ propByRes,
+ propByLinkedAccount,
+ null,
+ noPropResources);
+ if (!taskInfos.isEmpty()) {
+ taskInfos.get(0).setBeforeObj(Optional.of(beforeObj));
+ PropagationReporter reporter = new DefaultPropagationReporter();
+ taskExecutor.execute(taskInfos.get(0), reporter);
+ reportPropagation(result, reporter);
+ }
}
@Override
- protected AnyTO getAnyTO(final String key) {
- return userDataBinder.getUserTO(key);
+ protected void deprovision(final Any<?> any, final ConnectorObject beforeObj, final ProvisioningReport result) {
+ AnyTO before = getAnyTO(any.getKey());
+
+ List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource<String> propByRes = new PropagationByResource<>();
+ propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+ propByRes.addOldConnObjectKey(profile.getTask().getResource().getKey(), beforeObj.getUid().getUidValue());
+
+ PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
+ ((User) any).getLinkedAccounts(profile.getTask().getResource().getKey()).
+ forEach(account -> propByLinkedAccount.add(
+ ResourceOperation.DELETE,
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
+
+ List<PropagationTaskInfo> taskInfos = propagationManager.getDeleteTasks(
+ any.getType().getKind(),
+ any.getKey(),
+ propByRes,
+ propByLinkedAccount,
+ noPropResources);
+ if (!taskInfos.isEmpty()) {
+ taskInfos.get(0).setBeforeObj(Optional.of(beforeObj));
+ PropagationReporter reporter = new DefaultPropagationReporter();
+ taskExecutor.execute(taskInfos.get(0), reporter);
+ reportPropagation(result, reporter);
+ }
}
@Override
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushUtils.java
index b260fb5..8594401 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushUtils.java
@@ -27,6 +27,7 @@ import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.policy.PushCorrelationRuleEntity;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
import org.apache.syncope.core.provisioning.api.Connector;
import org.apache.syncope.core.provisioning.api.MappingManager;
import org.apache.syncope.core.provisioning.api.TimeoutException;
@@ -34,6 +35,7 @@ import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
import org.apache.syncope.core.spring.ImplementationManager;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.Name;
import org.identityconnectors.framework.common.objects.SearchResult;
import org.identityconnectors.framework.spi.SearchResultsHandler;
import org.slf4j.Logger;
@@ -137,4 +139,29 @@ public class PushUtils {
return obj == null ? Collections.emptyList() : Collections.singletonList(obj);
}
+
+ public ConnectorObject match(
+ final Connector connector,
+ final LinkedAccount account,
+ final Provision provision) {
+
+ Optional<? extends MappingItem> connObjectKey = MappingUtils.getConnObjectKeyItem(provision);
+ String connObjectKeyName = connObjectKey.isPresent()
+ ? connObjectKey.get().getExtAttrName()
+ : Name.NAME;
+
+ ConnectorObject obj = null;
+ try {
+ obj = connector.getObject(
+ provision.getObjectClass(),
+ AttributeBuilder.build(connObjectKeyName, account.getConnObjectKeyValue()),
+ provision.isIgnoreCaseMatch(),
+ MappingUtils.buildOperationOptions(provision.getMapping().getItems().iterator()));
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ }
+
+ return obj;
+ }
}
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
index f03042b..06769c2 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
@@ -75,7 +75,7 @@ public class DefaultUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
user.getLinkedAccounts().forEach(account -> propByLinkedAccount.add(
ResourceOperation.CREATE,
- Pair.of(account.getResource().getKey(), account.getConnObjectName())));
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
return new UserWorkflowResult<>(
Pair.of(user.getKey(), propagateEnable),
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateEndpoint.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateEndpoint.java
index 5936430..729cc04 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateEndpoint.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/component/PropagateEndpoint.java
@@ -91,7 +91,7 @@ public class PropagateEndpoint extends DefaultEndpoint {
producer = new DeleteProducer(this, anyTypeKind, userDAO, groupDataBinder);
break;
case provision:
- producer = new ProvisionProducer(this, anyTypeKind);
+ producer = new ProvisionProducer(this, anyTypeKind, userDAO);
break;
case deprovision:
producer = new DeprovisionProducer(this, anyTypeKind, userDAO, groupDAO, anyObjectDAO);
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeleteProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeleteProducer.java
index fce47dc..e765f71 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeleteProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeleteProducer.java
@@ -67,7 +67,7 @@ public class DeleteProducer extends AbstractProducer {
PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
userDAO.findLinkedAccounts(key).forEach(account -> propByLinkedAccount.add(
ResourceOperation.DELETE,
- Pair.of(account.getResource().getKey(), account.getConnObjectName())));
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
// Note here that we can only notify about "delete", not any other
// task defined in workflow process definition: this because this
@@ -93,6 +93,7 @@ public class DeleteProducer extends AbstractProducer {
AnyTypeKind.USER,
anyKey,
anyPropByRes,
+ null,
excludedResources)));
groupDataBinder.findAnyObjectsWithTransitiveResources(key).
forEach((anyKey, anyPropByRes) -> {
@@ -100,6 +101,7 @@ public class DeleteProducer extends AbstractProducer {
AnyTypeKind.ANY_OBJECT,
anyKey,
anyPropByRes,
+ null,
excludedResources));
});
// Generate propagation tasks for deleting this group from resources
@@ -107,6 +109,7 @@ public class DeleteProducer extends AbstractProducer {
AnyTypeKind.GROUP,
key,
null,
+ null,
null));
reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
exchange.setProperty("statuses", reporter.getStatuses());
@@ -117,6 +120,7 @@ public class DeleteProducer extends AbstractProducer {
AnyTypeKind.ANY_OBJECT,
key,
null,
+ null,
excludedResources);
reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
exchange.setProperty("statuses", reporter.getStatuses());
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeprovisionProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeprovisionProducer.java
index 4292737..cc91946 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeprovisionProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/DeprovisionProducer.java
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.stream.Collectors;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
@@ -66,10 +67,19 @@ public class DeprovisionProducer extends AbstractProducer {
switch (getAnyTypeKind()) {
case USER:
propByRes.set(ResourceOperation.DELETE, resources);
+
+ PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
+ userDAO.findLinkedAccounts(key).stream().
+ filter(account -> resources.contains(account.getResource().getKey())).
+ forEach(account -> propByLinkedAccount.add(
+ ResourceOperation.DELETE,
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
+
taskInfos = getPropagationManager().getDeleteTasks(
AnyTypeKind.USER,
key,
propByRes,
+ propByLinkedAccount,
userDAO.findAllResourceKeys(key).stream().
filter(resource -> !resources.contains(resource)).collect(Collectors.toList()));
propagationReporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
@@ -82,6 +92,7 @@ public class DeprovisionProducer extends AbstractProducer {
AnyTypeKind.GROUP,
key,
propByRes,
+ null,
groupDAO.findAllResourceKeys(key).stream().
filter(resource -> !resources.contains(resource)).collect(Collectors.toList()));
propagationReporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
@@ -94,6 +105,7 @@ public class DeprovisionProducer extends AbstractProducer {
AnyTypeKind.ANY_OBJECT,
key,
propByRes,
+ null,
anyObjectDAO.findAllResourceKeys(key).stream().
filter(resource -> !resources.contains(resource)).collect(Collectors.toList()));
propagationReporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ProvisionProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ProvisionProducer.java
index 62316f0..4bdfbf8 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ProvisionProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/ProvisionProducer.java
@@ -29,6 +29,7 @@ import org.apache.syncope.common.lib.patch.UserPatch;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.provisioning.api.PropagationByResource;
import org.apache.syncope.core.provisioning.api.UserWorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
@@ -36,8 +37,11 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo;
public class ProvisionProducer extends AbstractProducer {
- public ProvisionProducer(final Endpoint endpoint, final AnyTypeKind anyType) {
+ private final UserDAO userDAO;
+
+ public ProvisionProducer(final Endpoint endpoint, final AnyTypeKind anyType, final UserDAO userDAO) {
super(endpoint, anyType);
+ this.userDAO = userDAO;
}
@SuppressWarnings("unchecked")
@@ -77,6 +81,13 @@ public class ProvisionProducer extends AbstractProducer {
PropagationByResource<String> propByRes = new PropagationByResource<>();
propByRes.addAll(ResourceOperation.UPDATE, resources);
+ PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
+ userDAO.findLinkedAccounts(key).stream().
+ filter(account -> resources.contains(account.getResource().getKey())).
+ forEach(account -> propByLinkedAccount.add(
+ ResourceOperation.UPDATE,
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
+
AnyTypeKind anyTypeKind = AnyTypeKind.GROUP;
if (getAnyTypeKind() != null) {
anyTypeKind = getAnyTypeKind();
@@ -88,6 +99,7 @@ public class ProvisionProducer extends AbstractProducer {
false,
null,
propByRes,
+ propByLinkedAccount,
null,
null);
PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/StatusProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/StatusProducer.java
index 6be38e2..cc20d93 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/StatusProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/StatusProducer.java
@@ -91,12 +91,21 @@ public class StatusProducer extends AbstractProducer {
PropagationByResource<String> propByRes = new PropagationByResource<>();
propByRes.addAll(ResourceOperation.UPDATE, statusPatch.getResources());
+
+ PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
+ userDAO.findLinkedAccounts(statusPatch.getKey()).stream().
+ filter(account -> statusPatch.getResources().contains(account.getResource().getKey())).
+ forEach(account -> propByLinkedAccount.add(
+ ResourceOperation.UPDATE,
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
+
List<PropagationTaskInfo> taskInfos = getPropagationManager().getUpdateTasks(
AnyTypeKind.USER,
statusPatch.getKey(),
false,
statusPatch.getType() != StatusPatchType.SUSPEND,
propByRes,
+ propByLinkedAccount,
null,
null);
PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/UpdateProducer.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/UpdateProducer.java
index c658b07..0fd2b9f 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/UpdateProducer.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/producer/UpdateProducer.java
@@ -70,6 +70,7 @@ public class UpdateProducer extends AbstractProducer {
false,
null,
updated.getPropByRes(),
+ null,
((AnyPatch) actual).getVirAttrs(),
excludedResources);
PropagationReporter reporter = getPropagationTaskExecutor().execute(taskInfos, nullPriorityAsync);
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java
index b124e20..ec1bb4d 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java
@@ -147,7 +147,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter imp
PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
user.getLinkedAccounts().forEach(account -> propByLinkedAccount.add(
ResourceOperation.CREATE,
- Pair.of(account.getResource().getKey(), account.getConnObjectName())));
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
FlowableRuntimeUtils.saveForFormSubmit(
engine,
@@ -399,7 +399,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter imp
PropagationByResource<Pair<String, String>> propByLinkedAccount = new PropagationByResource<>();
user.getLinkedAccounts().forEach(account -> propByLinkedAccount.add(
ResourceOperation.DELETE,
- Pair.of(account.getResource().getKey(), account.getConnObjectName())));
+ Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue())));
if (engine.getRuntimeService().createProcessInstanceQuery().
processInstanceId(procInstID).active().list().isEmpty()) {
diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java
index f02cae4..700ff9d 100644
--- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java
+++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java
@@ -36,6 +36,7 @@ import javax.ws.rs.core.Response;
public interface UserService {
@GET
+ @Produces({ MediaType.APPLICATION_JSON })
List<User> list();
@GET
diff --git a/fit/build-tools/src/main/resources/log4j2.xml b/fit/build-tools/src/main/resources/log4j2.xml
index bab8707..7551796 100644
--- a/fit/build-tools/src/main/resources/log4j2.xml
+++ b/fit/build-tools/src/main/resources/log4j2.xml
@@ -33,8 +33,8 @@ under the License.
<appender-ref ref="main"/>
</asyncLogger>
- <root level="ERROR">
+ <root level="WARN">
<appenderRef ref="main"/>
</root>
</loggers>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
index 6c80c44..020db67 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
@@ -178,6 +178,8 @@ public abstract class AbstractITCase {
protected static final String RESOURCE_NAME_DBSCRIPTED = "resource-db-scripted";
+ protected static final String RESOURCE_NAME_REST = "rest-target-resource";
+
protected static final String RESOURCE_LDAP_ADMIN_DN = "uid=admin,ou=system";
protected static final String RESOURCE_LDAP_ADMIN_PWD = "secret";
@@ -618,6 +620,29 @@ public abstract class AbstractITCase {
}
}
+ protected void removeLdapRemoteObject(
+ final String bindDn,
+ final String bindPwd,
+ final String objectDn) {
+
+ InitialDirContext ctx = null;
+ try {
+ ctx = getLdapResourceDirContext(bindDn, bindPwd);
+
+ ctx.destroySubcontext(objectDn);
+ } catch (Exception e) {
+ LOG.error("While removing {}", objectDn, e);
+ } finally {
+ if (ctx != null) {
+ try {
+ ctx.close();
+ } catch (NamingException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
protected <T> T queryForObject(
final JdbcTemplate jdbcTemplate,
final int maxWaitSeconds,
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LinkedAccountITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LinkedAccountITCase.java
index 57d86bc..c6476e3 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LinkedAccountITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LinkedAccountITCase.java
@@ -18,45 +18,55 @@
*/
package org.apache.syncope.fit.core;
+import static org.apache.syncope.fit.AbstractITCase.getObject;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Optional;
+import java.util.UUID;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapContext;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.patch.LinkedAccountPatch;
import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.to.LinkedAccountTO;
import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.TaskTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ExecStatus;
+import org.apache.syncope.common.lib.types.MatchingRule;
import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
import org.apache.syncope.common.rest.api.beans.TaskQuery;
+import org.apache.syncope.common.rest.api.service.TaskService;
import org.apache.syncope.fit.AbstractITCase;
import org.junit.jupiter.api.Test;
public class LinkedAccountITCase extends AbstractITCase {
@Test
- public void createWithLinkedAccountThenRemove() throws NamingException {
+ public void createWithLinkedAccountThenUpdateThenRemove() throws NamingException {
// 1. create user with linked account
UserTO user = UserITCase.getSampleTO(
"linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
- String connObjectName = "uid=" + user.getUsername() + ",ou=People,o=isp";
+ String connObjectKeyValue = "uid=" + user.getUsername() + ",ou=People,o=isp";
String privilege = applicationService.read("mightyApp").getPrivileges().get(0).getKey();
- LinkedAccountTO account = new LinkedAccountTO.Builder().
- connObjectName(connObjectName).
- resource(RESOURCE_NAME_LDAP).
- build();
+ LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_LDAP, connObjectKeyValue).build();
account.getPlainAttrs().add(attrTO("surname", "LINKED_SURNAME"));
account.getPrivileges().add(privilege);
user.getLinkedAccounts().add(account);
@@ -70,12 +80,12 @@ public class LinkedAccountITCase extends AbstractITCase {
new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_LDAP).
anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
assertEquals(1, tasks.getTotalCount());
- assertEquals(connObjectName, tasks.getResult().get(0).getConnObjectKey());
+ assertEquals(connObjectKeyValue, tasks.getResult().get(0).getConnObjectKey());
assertEquals(ResourceOperation.CREATE, tasks.getResult().get(0).getOperation());
assertEquals(ExecStatus.SUCCESS.name(), tasks.getResult().get(0).getLatestExecStatus());
LdapContext ldapObj = (LdapContext) getLdapRemoteObject(
- RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectName);
+ RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectKeyValue);
assertNotNull(ldapObj);
Attributes ldapAttrs = ldapObj.getAttributes("");
@@ -84,9 +94,29 @@ public class LinkedAccountITCase extends AbstractITCase {
ldapAttrs.get("mail").getAll().next().toString());
assertEquals("LINKED_SURNAME", ldapAttrs.get("sn").getAll().next().toString());
- // 3. remove linked account from user
+ // 3. update linked account
UserPatch userPatch = new UserPatch();
userPatch.setKey(user.getKey());
+
+ account.getPlainAttrs().clear();
+ account.getPlainAttrs().add(attrTO("email", "UPDATED_EMAIL@syncope.apache.org"));
+ account.getPlainAttrs().add(attrTO("surname", "UPDATED_SURNAME"));
+ userPatch.getLinkedAccounts().add(new LinkedAccountPatch.Builder().linkedAccountTO(account).build());
+
+ user = updateUser(userPatch).getEntity();
+ assertEquals(1, user.getLinkedAccounts().size());
+
+ // 4 verify that account was updated on resource
+ ldapObj = (LdapContext) getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectKeyValue);
+ assertNotNull(ldapObj);
+
+ ldapAttrs = ldapObj.getAttributes("");
+ assertEquals("UPDATED_EMAIL@syncope.apache.org", ldapAttrs.get("mail").getAll().next().toString());
+ assertEquals("UPDATED_SURNAME", ldapAttrs.get("sn").getAll().next().toString());
+
+ // 5. remove linked account from user
+ userPatch = new UserPatch();
+ userPatch.setKey(user.getKey());
userPatch.getLinkedAccounts().add(new LinkedAccountPatch.Builder().
operation(PatchOperation.DELETE).
linkedAccountTO(user.getLinkedAccounts().get(0)).build());
@@ -94,19 +124,19 @@ public class LinkedAccountITCase extends AbstractITCase {
user = updateUser(userPatch).getEntity();
assertTrue(user.getLinkedAccounts().isEmpty());
- // 4. verify that propagation task was generated and that account is not any more on resource
+ // 6. verify that propagation task was generated and that account is not any more on resource
tasks = taskService.search(
new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_LDAP).
anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
- assertEquals(2, tasks.getTotalCount());
+ assertEquals(3, tasks.getTotalCount());
Optional<PropagationTaskTO> deletTask =
tasks.getResult().stream().filter(task -> task.getOperation() == ResourceOperation.DELETE).findFirst();
assertTrue(deletTask.isPresent());
- assertEquals(connObjectName, deletTask.get().getConnObjectKey());
+ assertEquals(connObjectKeyValue, deletTask.get().getConnObjectKey());
assertEquals(ExecStatus.SUCCESS.name(), deletTask.get().getLatestExecStatus());
- assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectName));
+ assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectKeyValue));
}
@Test
@@ -114,7 +144,7 @@ public class LinkedAccountITCase extends AbstractITCase {
// 1. create user without linked account
UserTO user = UserITCase.getSampleTO(
"linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
- String connObjectName = "uid=" + user.getUsername() + ",ou=People,o=isp";
+ String connObjectKeyValue = "uid=" + user.getUsername() + ",ou=People,o=isp";
user = createUser(user).getEntity();
assertNotNull(user.getKey());
@@ -125,16 +155,13 @@ public class LinkedAccountITCase extends AbstractITCase {
anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
assertEquals(0, tasks.getTotalCount());
- assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectName));
+ assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectKeyValue));
// 2. add linked account to user
UserPatch userPatch = new UserPatch();
userPatch.setKey(user.getKey());
- LinkedAccountTO account = new LinkedAccountTO.Builder().
- connObjectName(connObjectName).
- resource(RESOURCE_NAME_LDAP).
- build();
+ LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_LDAP, connObjectKeyValue).build();
account.getPlainAttrs().add(attrTO("surname", "LINKED_SURNAME"));
account.setPassword("Password123");
userPatch.getLinkedAccounts().add(new LinkedAccountPatch.Builder().linkedAccountTO(account).build());
@@ -147,12 +174,12 @@ public class LinkedAccountITCase extends AbstractITCase {
new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_LDAP).
anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
assertEquals(1, tasks.getTotalCount());
- assertEquals(connObjectName, tasks.getResult().get(0).getConnObjectKey());
+ assertEquals(connObjectKeyValue, tasks.getResult().get(0).getConnObjectKey());
assertEquals(ResourceOperation.CREATE, tasks.getResult().get(0).getOperation());
assertEquals(ExecStatus.SUCCESS.name(), tasks.getResult().get(0).getLatestExecStatus());
LdapContext ldapObj = (LdapContext) getLdapRemoteObject(
- RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectName);
+ RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, connObjectKeyValue);
assertNotNull(ldapObj);
Attributes ldapAttrs = ldapObj.getAttributes("");
@@ -161,4 +188,91 @@ public class LinkedAccountITCase extends AbstractITCase {
ldapAttrs.get("mail").getAll().next().toString());
assertEquals("LINKED_SURNAME", ldapAttrs.get("sn").getAll().next().toString());
}
+
+ @Test
+ public void push() {
+ // 0a. read configured cipher algorithm in order to be able to restore it at the end of test
+ AttrTO pwdCipherAlgo = configurationService.get("password.cipher.algorithm");
+ String origpwdCipherAlgo = pwdCipherAlgo.getValues().get(0);
+
+ // 0b. set AES password cipher algorithm
+ pwdCipherAlgo.getValues().set(0, "AES");
+ configurationService.set(pwdCipherAlgo);
+
+ try {
+ // 1. create user with linked account
+ UserTO user = UserITCase.getSampleTO(
+ "linkedAccount" + RandomStringUtils.randomNumeric(5) + "@syncope.apache.org");
+ String connObjectKeyValue = UUID.randomUUID().toString();
+
+ LinkedAccountTO account = new LinkedAccountTO.Builder(RESOURCE_NAME_REST, connObjectKeyValue).build();
+ user.getLinkedAccounts().add(account);
+
+ user = createUser(user).getEntity();
+ String userKey = user.getKey();
+ assertNotNull(userKey);
+ assertNotEquals(userKey, connObjectKeyValue);
+
+ // 2. verify that account is found on resource
+ PagedResult<PropagationTaskTO> tasks = taskService.search(
+ new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_REST).
+ anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
+ assertEquals(1, tasks.getTotalCount());
+ assertEquals(connObjectKeyValue, tasks.getResult().get(0).getConnObjectKey());
+ assertEquals(ResourceOperation.CREATE, tasks.getResult().get(0).getOperation());
+ assertEquals(ExecStatus.SUCCESS.name(), tasks.getResult().get(0).getLatestExecStatus());
+
+ WebClient webClient = WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/users/" + connObjectKeyValue).
+ accept(MediaType.APPLICATION_JSON_TYPE);
+ Response response = webClient.get();
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+ // 3. remove account from resource
+ response = webClient.delete();
+ assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+
+ response = webClient.get();
+ assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus());
+
+ // 4. create PushTask for the user above
+ PushTaskTO sendUser = new PushTaskTO();
+ sendUser.setName("Send User " + user.getUsername());
+ sendUser.setResource(RESOURCE_NAME_REST);
+ sendUser.setUnmatchingRule(UnmatchingRule.PROVISION);
+ sendUser.setMatchingRule(MatchingRule.UPDATE);
+ sendUser.setSourceRealm(SyncopeConstants.ROOT_REALM);
+ sendUser.getFilters().put(AnyTypeKind.USER.name(), "username==" + user.getUsername());
+ sendUser.setPerformCreate(true);
+ sendUser.setPerformUpdate(true);
+
+ response = taskService.create(TaskType.PUSH, sendUser);
+ sendUser = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+ assertNotNull(sendUser);
+
+ // 5. execute PushTask
+ AbstractTaskITCase.execProvisioningTask(taskService, TaskType.PUSH, sendUser.getKey(), 50, false);
+
+ TaskTO task = taskService.read(TaskType.PUSH, sendUser.getKey(), true);
+ assertEquals(1, task.getExecutions().size());
+ assertEquals(ExecStatus.SUCCESS.name(), task.getExecutions().get(0).getStatus());
+
+ tasks = taskService.search(
+ new TaskQuery.Builder(TaskType.PROPAGATION).resource(RESOURCE_NAME_REST).
+ anyTypeKind(AnyTypeKind.USER).entityKey(user.getKey()).build());
+ assertEquals(3, tasks.getTotalCount());
+
+ // 6. verify that both user and account are now found on resource
+ response = webClient.get();
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+ webClient = WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/users/" + userKey).
+ accept(MediaType.APPLICATION_JSON_TYPE);
+ response = webClient.get();
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+ } finally {
+ // restore initial cipher algorithm
+ pwdCipherAlgo.getValues().set(0, origpwdCipherAlgo);
+ configurationService.set(pwdCipherAlgo);
+ }
+ }
}
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
index da4570b..b9b61f2 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
@@ -108,8 +108,8 @@ public class PushTaskITCase extends AbstractTaskITCase {
SyncopeClient.getGroupSearchConditionBuilder().isNotNull("cool").query());
task.setMatchingRule(MatchingRule.LINK);
- final Response response = taskService.create(TaskType.PUSH, task);
- final PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+ Response response = taskService.create(TaskType.PUSH, task);
+ PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
assertNotNull(actual);
task = taskService.read(TaskType.PUSH, actual.getKey(), true);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
index 5956fcd..29ab274 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
@@ -1322,7 +1322,7 @@ public class UserITCase extends AbstractITCase {
public void restResource() {
UserTO userTO = getUniqueSampleTO("rest@syncope.apache.org");
userTO.getResources().clear();
- userTO.getResources().add("rest-target-resource");
+ userTO.getResources().add(RESOURCE_NAME_REST);
// 1. create
ProvisioningResult<UserTO> result = userService.create(userTO, true).readEntity(
@@ -1330,13 +1330,13 @@ public class UserITCase extends AbstractITCase {
});
assertEquals(1, result.getPropagationStatuses().size());
assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
- assertEquals("rest-target-resource", result.getPropagationStatuses().get(0).getResource());
+ assertEquals(RESOURCE_NAME_REST, result.getPropagationStatuses().get(0).getResource());
assertEquals("surname", userTO.getPlainAttr("surname").get().getValues().get(0));
// verify user exists on the backend REST service
WebClient webClient = WebClient.create(BUILD_TOOLS_ADDRESS + "/rest/users/" + result.getEntity().getKey());
Response response = webClient.get();
- assertEquals(200, response.getStatus());
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
assertNotNull(response.getEntity());
// 2. update
@@ -1349,12 +1349,12 @@ public class UserITCase extends AbstractITCase {
});
assertEquals(1, result.getPropagationStatuses().size());
assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
- assertEquals("rest-target-resource", result.getPropagationStatuses().get(0).getResource());
+ assertEquals(RESOURCE_NAME_REST, result.getPropagationStatuses().get(0).getResource());
assertEquals("surname2", result.getEntity().getPlainAttr("surname").get().getValues().get(0));
// verify user still exists on the backend REST service
response = webClient.get();
- assertEquals(200, response.getStatus());
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
assertNotNull(response.getEntity());
// 3. delete
@@ -1363,10 +1363,10 @@ public class UserITCase extends AbstractITCase {
});
assertEquals(1, result.getPropagationStatuses().size());
assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
- assertEquals("rest-target-resource", result.getPropagationStatuses().get(0).getResource());
+ assertEquals(RESOURCE_NAME_REST, result.getPropagationStatuses().get(0).getResource());
// verify user was removed by the backend REST service
- assertEquals(404, webClient.get().getStatus());
+ assertEquals(Response.Status.NOT_FOUND.getStatusCode(), webClient.get().getStatus());
}
@Test
diff --git a/fit/core-reference/src/test/resources/rest/CreateScript.groovy b/fit/core-reference/src/test/resources/rest/CreateScript.groovy
index f97961e..98bb496 100644
--- a/fit/core-reference/src/test/resources/rest/CreateScript.groovy
+++ b/fit/core-reference/src/test/resources/rest/CreateScript.groovy
@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ObjectNode
import org.apache.cxf.jaxrs.client.WebClient
import org.identityconnectors.framework.common.objects.Uid
+import javax.ws.rs.core.Response
// Parameters:
// The connector sends us the following:
@@ -51,10 +52,15 @@ case "__ACCOUNT__":
node.set("email", node.textNode(attributes.get("email").get(0)));
String payload = mapper.writeValueAsString(node);
-
+
webClient.path("/users");
- webClient.post(payload);
+
+ log.ok("Sending POST to {0} with payload {1}", webClient.getCurrentURI().toASCIIString(), payload);
+
+ Response response = webClient.post(payload);
+ log.ok("Create response: {0} {1}", response.getStatus(), response.getHeaders());
+
key = node.get("key").textValue();
break
diff --git a/fit/core-reference/src/test/resources/rest/DeleteScript.groovy b/fit/core-reference/src/test/resources/rest/DeleteScript.groovy
index 7cf805a..f78355e 100644
--- a/fit/core-reference/src/test/resources/rest/DeleteScript.groovy
+++ b/fit/core-reference/src/test/resources/rest/DeleteScript.groovy
@@ -17,6 +17,7 @@
* under the License.
*/
import org.apache.cxf.jaxrs.client.WebClient
+import javax.ws.rs.core.Response
// Parameters:
// The connector sends the following:
@@ -36,7 +37,12 @@ assert uid != null
switch ( objectClass ) {
case "__ACCOUNT__":
webClient.path("/users/" + uid);
- webClient.delete();
+
+ log.ok("Sending DELETE to {0}", webClient.getCurrentURI().toASCIIString());
+
+ Response response = webClient.delete();
+
+ log.ok("Delete response: {0} {1}", response.getStatus(), response.getHeaders());
break
default:
diff --git a/fit/core-reference/src/test/resources/rest/SearchScript.groovy b/fit/core-reference/src/test/resources/rest/SearchScript.groovy
index ba7a2e8..a6f5abe 100644
--- a/fit/core-reference/src/test/resources/rest/SearchScript.groovy
+++ b/fit/core-reference/src/test/resources/rest/SearchScript.groovy
@@ -22,7 +22,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode
import javax.ws.rs.core.Response
import org.apache.cxf.jaxrs.client.WebClient
import org.identityconnectors.common.security.GuardedString
-import org.identityconnectors.framework.common.objects.OperationOptions;
+import org.identityconnectors.framework.common.objects.OperationOptions
// Parameters:
// The connector sends the following:
@@ -92,9 +92,18 @@ def result = []
switch (objectClass) {
case "__ACCOUNT__":
- if (query == null || (!query.get("left").equals("__UID__") && !query.get("conditionType").equals("EQUALS"))) {
+ if (query == null
+ || (!query.get("left").equals("__UID__") && !query.get("left").equals("key")
+ && !query.get("conditionType").equals("EQUALS"))) {
+
webClient.path("/users");
+
+ log.ok("Sending GET to {0}", webClient.getCurrentURI().toASCIIString());
+
Response response = webClient.get();
+
+ log.ok("LIST response: {0} {1}", response.getStatus(), response.getHeaders());
+
ArrayNode nodes = mapper.readTree(response.getEntity());
// beware: this is not enforcing any server-side pagination feature
@@ -103,7 +112,13 @@ case "__ACCOUNT__":
}
} else {
webClient.path("/users/" + query.get("right"));
+
+ log.ok("Sending GET to {0}", webClient.getCurrentURI().toASCIIString());
+
Response response = webClient.get();
+
+ log.ok("READ response: {0} {1}", response.getStatus(), response.getHeaders());
+
if (response.getStatus() == 200) {
ObjectNode node = mapper.readTree(response.getEntity());
result.add(buildConnectorObject(node));
diff --git a/fit/core-reference/src/test/resources/rest/UpdateScript.groovy b/fit/core-reference/src/test/resources/rest/UpdateScript.groovy
index c0d258a..95cae71 100644
--- a/fit/core-reference/src/test/resources/rest/UpdateScript.groovy
+++ b/fit/core-reference/src/test/resources/rest/UpdateScript.groovy
@@ -19,6 +19,7 @@
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ObjectNode
import org.apache.cxf.jaxrs.client.WebClient
+import javax.ws.rs.core.Response
// Parameters:
// The connector sends us the following:
@@ -81,8 +82,13 @@ case "UPDATE":
// this if update works with PUT
webClient.path("users").path(uid);
- webClient.put(payload);
+ log.ok("Sending PUT to {0} with payload {1}", webClient.getCurrentURI().toASCIIString(), payload);
+
+ Response response = webClient.put(payload);
+
+ log.ok("Update response: {0} {1}", response.getStatus(), response.getHeaders());
+
// this instead if update works with PATCH
//webClient.path("users").path(uid);
//WebClient.getConfig(webClient).getRequestContext().put("use.async.http.conduit", true);