From be22f689e688485880f426057797238906dee848 Mon Sep 17 00:00:00 2001
From: Julien CORNILLE <julien.cornille@xelians.fr>
Date: Thu, 22 Apr 2021 09:39:53 +0200
Subject: [PATCH] [US RABB-1166] Fix

---
 .../iam/common/dto}/ProvidedUserDto.java      |   3 +-
 api/api-iam/iam-internal/README.md            |  49 ++++++
 .../config/iam-internal-application-dev.yml   |  16 +-
 .../cas/service/CasInternalService.java       |  54 +++++--
 .../server/config/ApiIamServerConfig.java     |   6 +-
 .../client/ProvisioningWebClient.java         |  93 ++++++++++++
 .../IdPProvisioningClientConfiguration.java   |   5 +-
 .../ProvisioningClientConfiguration.java      |   2 +-
 .../service/ProvisioningInternalService.java  |  78 +++++-----
 .../server/rest/CasInternalController.java    |   4 +-
 .../server/user/dao/UserRepository.java       |   2 +
 .../cas/service/CasInternalServiceTest.java   |  57 ++++---
 .../client/ProvisioningWebClientTest.java     | 119 +++++++++++++++
 .../ProvisioningInternalServiceTest.java      | 143 ++++++++++++++++++
 14 files changed, 540 insertions(+), 91 deletions(-)
 rename {commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/domain => api/api-iam/iam-commons/src/main/java/fr/gouv/vitamui/iam/common/dto}/ProvidedUserDto.java (90%)
 create mode 100644 api/api-iam/iam-internal/README.md
 create mode 100644 api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/client/ProvisioningWebClient.java
 rename {commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/client/configuration => api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/config}/IdPProvisioningClientConfiguration.java (92%)
 rename {commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/client/configuration => api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/config}/ProvisioningClientConfiguration.java (97%)
 create mode 100644 api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/provisioning/client/ProvisioningWebClientTest.java
 create mode 100644 api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/provisioning/service/ProvisioningInternalServiceTest.java

diff --git a/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/domain/ProvidedUserDto.java b/api/api-iam/iam-commons/src/main/java/fr/gouv/vitamui/iam/common/dto/ProvidedUserDto.java
similarity index 90%
rename from commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/domain/ProvidedUserDto.java
rename to api/api-iam/iam-commons/src/main/java/fr/gouv/vitamui/iam/common/dto/ProvidedUserDto.java
index a0a1e48ff..74ebb87b4 100644
--- a/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/domain/ProvidedUserDto.java
+++ b/api/api-iam/iam-commons/src/main/java/fr/gouv/vitamui/iam/common/dto/ProvidedUserDto.java
@@ -1,4 +1,4 @@
-package fr.gouv.vitamui.commons.api.domain;
+package fr.gouv.vitamui.iam.common.dto;
 
 import org.hibernate.validator.constraints.Length;
 
@@ -8,6 +8,7 @@ import javax.validation.constraints.Email;
 import javax.validation.constraints.NotNull;
 
 import fr.gouv.vitamui.commons.api.deserializer.ToLowerCaseConverter;
+import fr.gouv.vitamui.commons.api.domain.AddressDto;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
diff --git a/api/api-iam/iam-internal/README.md b/api/api-iam/iam-internal/README.md
new file mode 100644
index 000000000..001b908c8
--- /dev/null
+++ b/api/api-iam/iam-internal/README.md
@@ -0,0 +1,49 @@
+# Presentation
+
+This module is a set of REST/JSON web services to perform CRUD operations on the business models:
+
+- customers
+- tenants
+- identity providers
+- profile groups
+- profiles
+- users.
+
+
+# Run the web services
+
+```shell
+mvn spring-boot:run
+```
+
+# Provisioning
+
+The users can be provided by a tier service
+
+To enable this function, you must configure an external identity provider with the property autoprovisioning set to true.
+
+At the module level, you must add properties to do the mapping between the identity provider and the webservice to call
+
+Example : **application.yml**
+
+``` 
+    provisioning-client:
+        identity-providers:
+            - idp-identifier: system_idp
+              uri: https://localhost:8090/provisioning/v1/users
+              client:
+                secure: true
+                ssl-configuration:
+                    keystore:
+                    key-path: src/main/config/keystore_provisioning-users.jks
+                    key-password: changeme
+                    type: JKS
+                truststore:
+                    key-path: src/main/config/truststore_server.jks
+                    key-password: changeme
+                    type: JKS
+                hostname-verification: false
+```
+
+Please note that the configuration take a list in input
+
diff --git a/api/api-iam/iam-internal/src/main/config/iam-internal-application-dev.yml b/api/api-iam/iam-internal/src/main/config/iam-internal-application-dev.yml
index 7b44aa02b..e459151a4 100644
--- a/api/api-iam/iam-internal/src/main/config/iam-internal-application-dev.yml
+++ b/api/api-iam/iam-internal/src/main/config/iam-internal-application-dev.yml
@@ -84,33 +84,31 @@ logging:
 
 provisioning-client:
   identity-providers:
-    - idp-identifier: 1
+    - idp-identifier: system_idp
+      uri: https://localhost:8090/provisioning/v1/users
       client:
-        server-host: ${vitamui-server-host}.teamdlab.com
-        server-port: 6201
         secure: true
         ssl-configuration:
           keystore:
-            key-path: ../../../dev-deployment/environment/keystores/server/localhost/keystore_archive-internal.jks
+            key-path: src/main/config/keystore_provisioning-users.jks
             key-password: changeme
             type: JKS
           truststore:
-            key-path: ../../../dev-deployment/environment/keystores/server/truststore_server.jks
+            key-path: src/main/config/truststore_server.jks
             key-password: changeme
             type: JKS
           hostname-verification: false
     - idp-identifier: 2
       client:
-        server-host: ${vitamui-server-host}.teamdlab.com
-        server-port: 6201
+        uri: https://localhost:8090/provisioning/v1/users
         secure: true
         ssl-configuration:
           keystore:
-            key-path: ../../../dev-deployment/environment/keystores/server/localhost/keystore_archive-internal.jks
+            key-path: src/main/config/keystore_provisioning-users.jks
             key-password: changeme
             type: JKS
           truststore:
-            key-path: ../../../dev-deployment/environment/keystores/server/truststore_server.jks
+            key-path: src/main/config/truststore_server.jks
             key-password: changeme
             type: JKS
           hostname-verification: false
diff --git a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/cas/service/CasInternalService.java b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/cas/service/CasInternalService.java
index 836c01b23..cfcbfd41e 100644
--- a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/cas/service/CasInternalService.java
+++ b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/cas/service/CasInternalService.java
@@ -66,7 +66,7 @@ import javax.validation.constraints.NotNull;
 import fr.gouv.vitamui.commons.api.CommonConstants;
 import fr.gouv.vitamui.commons.api.domain.CriterionOperator;
 import fr.gouv.vitamui.commons.api.domain.GroupDto;
-import fr.gouv.vitamui.commons.api.domain.ProvidedUserDto;
+import fr.gouv.vitamui.iam.common.dto.ProvidedUserDto;
 import fr.gouv.vitamui.commons.api.domain.QueryDto;
 import fr.gouv.vitamui.commons.api.domain.UserDto;
 import fr.gouv.vitamui.commons.api.enums.UserStatusEnum;
@@ -293,25 +293,53 @@ public class CasInternalService {
         }
     }
 
+    /**
+     * Method to retrieve the user informations
+     * @param email email of the user
+     * @param idp can be null
+     * @param userIdentifier can be null
+     * @param optEmbedded
+     * @return
+     */
     @Transactional
-    public UserDto getUser(final String email, final String idp, final Optional<String> userIdentifier, final Optional<String> optEmbedded) {
+    public UserDto getUser(final String email, final String idp, final String userIdentifier, final String optEmbedded) {
+       // if the user depends on an external idp
+        if(StringUtils.isNotBlank(idp)) {
+            this.provisionUser(email, idp, userIdentifier);
+        }
+
+        return getUserByEmail(email, Optional.ofNullable(optEmbedded));
+    }
+
+    /**
+     * Method to perform auto provisioning
+     * @param email
+     * @param idp
+     * @param userIdentifier
+     */
+    public void provisionUser(final String email, final String idp, final String userIdentifier) {
         final IdentityProviderDto identityProvider = identityProviderInternalService.getOne(idp);
-        try {
+
+        // Do nothing is autoProvisioning is disabled
+        if(!identityProvider.isAutoProvisioningEnabled()) {
+            return;
+        }
+
+        final boolean userExist = userRepository.existsByEmail(email);
+        // Try to update user
+        if(userExist) {
             final UserDto user = internalUserService.findUserByEmail(email);
-            if (identityProvider.isAutoProvisioningEnabled() && user.isAutoProvisioningEnabled()) {
-                // TODO : quelle unité envoyer ?
-                updateUser(user, provisioningInternalService.getUserInformation(email, idp, Optional.of(user.getGroupId()), Optional.empty(), userIdentifier));
-            }
-        } catch (NotFoundException e) {
-            if (!identityProvider.isAutoProvisioningEnabled()) {
-                throw e;
+            if(user.isAutoProvisioningEnabled()) {
+                updateUser(user, provisioningInternalService.getUserInformation(idp, email, user.getGroupId(), null, userIdentifier));
             }
-            createNewUser(provisioningInternalService.getUserInformation(email, idp, Optional.empty(), Optional.empty(), userIdentifier));
         }
-
-        return getUserByEmail(email, optEmbedded);
+        // Try to create a new user
+        else {
+            createNewUser(provisioningInternalService.getUserInformation(idp, email, null, null, null));
+        }
     }
 
+
     private void createNewUser(final ProvidedUserDto providedUserInfo) {
         final UserDto user = new UserDto();
         user.setType(UserTypeEnum.NOMINATIVE);
diff --git a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/config/ApiIamServerConfig.java b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/config/ApiIamServerConfig.java
index bf07e6d5b..2f166e6ef 100644
--- a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/config/ApiIamServerConfig.java
+++ b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/config/ApiIamServerConfig.java
@@ -42,7 +42,7 @@ import fr.gouv.vitamui.commons.mongo.config.MongoConfig;
 import fr.gouv.vitamui.commons.mongo.dao.CustomSequenceRepository;
 import fr.gouv.vitamui.commons.rest.RestExceptionHandler;
 import fr.gouv.vitamui.commons.rest.client.BaseRestClientFactory;
-import fr.gouv.vitamui.commons.rest.client.configuration.ProvisioningClientConfiguration;
+import fr.gouv.vitamui.iam.internal.server.provisioning.config.ProvisioningClientConfiguration;
 import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration;
 import fr.gouv.vitamui.commons.rest.configuration.SwaggerConfiguration;
 import fr.gouv.vitamui.commons.vitam.api.access.LogbookService;
@@ -334,8 +334,8 @@ public class ApiIamServerConfig extends AbstractContextConfiguration {
     }
 
     @Bean
-    public ProvisioningInternalService provisioningService(final WebClient.Builder webClientBuilder, final ProvisioningClientConfiguration provisioningClientConfiguration) {
-        return new ProvisioningInternalService(webClientBuilder, provisioningClientConfiguration);
+    public ProvisioningInternalService provisioningService(final WebClient.Builder webClientBuilder, final ProvisioningClientConfiguration provisioningClientConfiguration, final InternalSecurityService internalSecurityService) {
+        return new ProvisioningInternalService(webClientBuilder, provisioningClientConfiguration, internalSecurityService);
     }
 
     @Bean
diff --git a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/client/ProvisioningWebClient.java b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/client/ProvisioningWebClient.java
new file mode 100644
index 000000000..15d26016e
--- /dev/null
+++ b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/client/ProvisioningWebClient.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020)
+ * and the signatories of the "VITAM - Accord du Contributeur" agreement.
+ *
+ * contact@programmevitam.fr
+ *
+ * This software is a computer program whose purpose is to implement
+ * implement a digital archiving front-office system for the secure and
+ * efficient high volumetry VITAM solution.
+ *
+ * This software is governed by the CeCILL-C license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-C
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+ */
+package fr.gouv.vitamui.iam.internal.server.provisioning.client;
+
+import java.net.URI;
+import java.util.Optional;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.client.utils.URIBuilder;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import fr.gouv.vitamui.iam.common.dto.ProvidedUserDto;
+import fr.gouv.vitamui.commons.api.logger.VitamUILogger;
+import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory;
+import fr.gouv.vitamui.commons.rest.client.BaseCrudWebClient;
+import fr.gouv.vitamui.commons.rest.client.BaseWebClient;
+import fr.gouv.vitamui.commons.rest.client.InternalHttpContext;
+
+/**
+ * External WebClient for Customer operations.
+ *
+ *
+ */
+public class ProvisioningWebClient extends BaseWebClient<InternalHttpContext> {
+
+    private static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(ProvisioningWebClient.class);
+
+    public ProvisioningWebClient(final WebClient webClient, final String baseUrl) {
+        super(webClient, baseUrl);
+    }
+
+    public ProvidedUserDto getProvidedUser(final InternalHttpContext context, final String email, final String groupId, final String unit, final String technicalUserId)  {
+
+        final URIBuilder builder = getUriBuilderFromUrl();
+
+        if (StringUtils.isNotBlank(email)) {
+            builder.addParameter("email", email);
+        }
+        if (StringUtils.isNotBlank(groupId)) {
+            builder.addParameter("groupId", groupId);
+        }
+        if (StringUtils.isNotBlank(unit)) {
+            builder.addParameter("unit", unit);
+        }
+        if (StringUtils.isNotBlank(technicalUserId)) {
+            builder.addParameter("technicalUserId", technicalUserId);
+        }
+
+        return webClient.get().uri(buildUriBuilder(builder)).headers(headersConsumer -> headersConsumer.addAll(buildHeaders(context))).retrieve().onStatus(status -> !status.is2xxSuccessful(), BaseCrudWebClient::createResponseException)
+            .bodyToMono(ProvidedUserDto.class).block();
+    }
+    
+    //PATH URL is given by configuration
+    @Override
+    public String getPathUrl() {
+        return StringUtils.EMPTY;
+    }
+
+}
diff --git a/commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/client/configuration/IdPProvisioningClientConfiguration.java b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/config/IdPProvisioningClientConfiguration.java
similarity index 92%
rename from commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/client/configuration/IdPProvisioningClientConfiguration.java
rename to api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/config/IdPProvisioningClientConfiguration.java
index defedf49f..30ae5b19e 100644
--- a/commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/client/configuration/IdPProvisioningClientConfiguration.java
+++ b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/config/IdPProvisioningClientConfiguration.java
@@ -34,8 +34,9 @@
  * The fact that you are presently reading this means that you have had
  * knowledge of the CeCILL-C license and that you accept its terms.
  */
-package fr.gouv.vitamui.commons.rest.client.configuration;
+package fr.gouv.vitamui.iam.internal.server.provisioning.config;
 
+import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
@@ -47,7 +48,7 @@ import lombok.ToString;
 @ToString
 public class IdPProvisioningClientConfiguration {
 
-    private Integer idpIdentifier;
+    private String idpIdentifier;
 
     private String uri;
 
diff --git a/commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/client/configuration/ProvisioningClientConfiguration.java b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/config/ProvisioningClientConfiguration.java
similarity index 97%
rename from commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/client/configuration/ProvisioningClientConfiguration.java
rename to api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/config/ProvisioningClientConfiguration.java
index cc3bffb0f..2693bb797 100644
--- a/commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/client/configuration/ProvisioningClientConfiguration.java
+++ b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/config/ProvisioningClientConfiguration.java
@@ -34,7 +34,7 @@
  * The fact that you are presently reading this means that you have had
  * knowledge of the CeCILL-C license and that you accept its terms.
  */
-package fr.gouv.vitamui.commons.rest.client.configuration;
+package fr.gouv.vitamui.iam.internal.server.provisioning.config;
 
 import java.util.List;
 
diff --git a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/service/ProvisioningInternalService.java b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/service/ProvisioningInternalService.java
index f232eaf42..0f58d0e2a 100644
--- a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/service/ProvisioningInternalService.java
+++ b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/provisioning/service/ProvisioningInternalService.java
@@ -1,25 +1,25 @@
 /**
  * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020)
  * and the signatories of the "VITAM - Accord du Contributeur" agreement.
- * <p>
+ *
  * contact@programmevitam.fr
- * <p>
+ *
  * This software is a computer program whose purpose is to implement
  * implement a digital archiving front-office system for the secure and
  * efficient high volumetry VITAM solution.
- * <p>
+ *
  * This software is governed by the CeCILL-C license under French law and
  * abiding by the rules of distribution of free software.  You can  use,
  * modify and/ or redistribute the software under the terms of the CeCILL-C
  * license as circulated by CEA, CNRS and INRIA at the following URL
  * "http://www.cecill.info".
- * <p>
+ *
  * As a counterpart to the access to the source code and  rights to copy,
  * modify and redistribute granted by the license, users are provided only
  * with a limited warranty  and the software's author,  the holder of the
  * economic rights,  and the successive licensors  have only  limited
  * liability.
- * <p>
+ *
  * In this respect, the user's attention is drawn to the risks associated
  * with loading,  using,  modifying and/or developing or reproducing the
  * software by the user in light of its specific status of free software,
@@ -30,7 +30,7 @@
  * requirements in conditions enabling the security of their systems and/or
  * data to be ensured and,  more generally, to use and operate it in the
  * same conditions as regards security.
- * <p>
+ *
  * The fact that you are presently reading this means that you have had
  * knowledge of the CeCILL-C license and that you accept its terms.
  */
@@ -39,16 +39,16 @@ package fr.gouv.vitamui.iam.internal.server.provisioning.service;
 
 import java.util.Optional;
 
-import org.jetbrains.annotations.NotNull;
 import org.springframework.stereotype.Service;
 import org.springframework.web.reactive.function.client.WebClient;
-import org.springframework.web.util.UriComponentsBuilder;
 
-import fr.gouv.vitamui.commons.api.domain.ProvidedUserDto;
+import fr.gouv.vitamui.iam.common.dto.ProvidedUserDto;
 import fr.gouv.vitamui.commons.api.exception.NotFoundException;
 import fr.gouv.vitamui.commons.rest.client.BaseWebClientFactory;
-import fr.gouv.vitamui.commons.rest.client.configuration.IdPProvisioningClientConfiguration;
-import fr.gouv.vitamui.commons.rest.client.configuration.ProvisioningClientConfiguration;
+import fr.gouv.vitamui.iam.internal.server.provisioning.config.IdPProvisioningClientConfiguration;
+import fr.gouv.vitamui.iam.internal.server.provisioning.config.ProvisioningClientConfiguration;
+import fr.gouv.vitamui.iam.internal.server.provisioning.client.ProvisioningWebClient;
+import fr.gouv.vitamui.iam.security.service.InternalSecurityService;
 
 /**
  * Customer provisioning service.
@@ -62,38 +62,44 @@ public class ProvisioningInternalService {
 
     private final ProvisioningClientConfiguration provisioningClientConfiguration;
 
-    public ProvisioningInternalService(final WebClient.Builder webClientBuilder, final ProvisioningClientConfiguration provisioningClientConfiguration) {
+    private final InternalSecurityService securityService;
+
+    public ProvisioningInternalService(final WebClient.Builder webClientBuilder, final ProvisioningClientConfiguration provisioningClientConfiguration,
+        final InternalSecurityService securityService) {
         this.webClientBuilder = webClientBuilder;
         this.provisioningClientConfiguration = provisioningClientConfiguration;
+        this.securityService = securityService;
     }
 
-    public ProvidedUserDto getUserInformation(final String email, final String idp, Optional<String> groupId, Optional<String> unit, final Optional<String> technicalUserId) {
-        final IdPProvisioningClientConfiguration idpProvisioningClient =
-                provisioningClientConfiguration.getIdentityProviders().stream().filter(provisioningClient -> provisioningClient.getIdpIdentifier().equals(idp))
-                        .findFirst().orElseThrow(() -> new NotFoundException(String.format("Provisioning client configuration not found for IdP : {}", idp)));
-        final BaseWebClientFactory clientFactory = new BaseWebClientFactory(idpProvisioningClient.getClient(), webClientBuilder);
+    public ProvidedUserDto getUserInformation(final String idp, final String email, final String groupId, final String unit, final String technicalUserId) {
+        final IdPProvisioningClientConfiguration idpProvisioningClient = getProvisioningClientConfiguration(idp);
 
-        return clientFactory.getWebClient().get()
-                .uri(getUri(email, groupId, unit, technicalUserId, idpProvisioningClient))
-                .retrieve().bodyToMono(ProvidedUserDto.class).block();
-    }
+        var webClient = buildWebClient(idpProvisioningClient);
 
-    @NotNull
-    private String getUri(final String email, final Optional<String> groupId, final Optional<String> unit, final Optional<String> technicalUserId,
-            final IdPProvisioningClientConfiguration idpProvisioningClient) {
-        final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(idpProvisioningClient.getUri());
-        uriBuilder.queryParam("email", email);
-        if (groupId.isPresent()) {
-            uriBuilder.queryParam("groupId", groupId);
-        }
-        if (unit.isPresent()) {
-            uriBuilder.queryParam("unit", unit.get());
-        }
-        if (technicalUserId.isPresent()) {
-            uriBuilder.queryParam("technicalUserId", technicalUserId.get());
-        }
+        return webClient.getProvidedUser(securityService.getHttpContext(), email, groupId, unit, technicalUserId);
+    }
 
-        return uriBuilder.toUriString();
+    /**
+     *
+     * @param idp
+     * @return
+     */
+    protected IdPProvisioningClientConfiguration getProvisioningClientConfiguration(final String idp) {
+        return provisioningClientConfiguration.getIdentityProviders()
+            .stream()
+            .filter(provisioningClient -> provisioningClient.getIdpIdentifier().equals(idp))
+            .findFirst().orElseThrow(() -> new NotFoundException(String.format("Provisioning client configuration not found for IdP : %S", idp)));
     }
 
+    /**
+     * Method for build webClient
+     * @param idpProvisioningClient
+     * @return
+     */
+    protected ProvisioningWebClient buildWebClient(final IdPProvisioningClientConfiguration idpProvisioningClient) {
+        final BaseWebClientFactory clientFactory = new BaseWebClientFactory(idpProvisioningClient.getClient(), null ,this.webClientBuilder,
+            idpProvisioningClient.getUri());
+
+        return new ProvisioningWebClient(clientFactory.getWebClient(), idpProvisioningClient.getUri());
+    }
 }
diff --git a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/rest/CasInternalController.java b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/rest/CasInternalController.java
index 22aaa6a35..bbe605f00 100644
--- a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/rest/CasInternalController.java
+++ b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/rest/CasInternalController.java
@@ -191,8 +191,8 @@ public class CasInternalController {
     }
 
     @GetMapping(value = RestApi.CAS_USERS_PATH + RestApi.USERS_PROVISIONING, params = { "email", "idp" })
-    public UserDto getUser(@RequestParam final String email, @RequestParam final String idp, @RequestParam final Optional<String> userIdentifier,
-            final @RequestParam Optional<String> embedded) {
+    public UserDto getUser(@RequestParam final String email, @RequestParam final String idp, @RequestParam(required = false) final String userIdentifier,
+            @RequestParam(required = false) final String embedded) {
         LOGGER.debug("getUser - email : {}, idp : {}, userIdentifier : {}, embedded options : {}", email, idp, userIdentifier, embedded);
         return casService.getUser(email, idp, userIdentifier, embedded);
     }
diff --git a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/user/dao/UserRepository.java b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/user/dao/UserRepository.java
index 6ce8a65a0..d5296ee23 100644
--- a/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/user/dao/UserRepository.java
+++ b/api/api-iam/iam-internal/src/main/java/fr/gouv/vitamui/iam/internal/server/user/dao/UserRepository.java
@@ -58,6 +58,8 @@ public interface UserRepository extends VitamUIRepository<User, String> {
 
     User findByEmail(String email);
 
+    boolean existsByEmail(String email);
+
     long countByGroupId(String profileGroupId);
 
     Page<User> findByCustomerIdAndSubrogeableAndTypeAndStatus(String customerId, boolean subrogeable, UserTypeEnum type, UserStatusEnum status,
diff --git a/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/cas/service/CasInternalServiceTest.java b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/cas/service/CasInternalServiceTest.java
index 94e52b8de..c5613e394 100644
--- a/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/cas/service/CasInternalServiceTest.java
+++ b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/cas/service/CasInternalServiceTest.java
@@ -2,7 +2,6 @@ package fr.gouv.vitamui.iam.internal.server.cas.service;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -13,20 +12,23 @@ import java.util.Optional;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+import org.mockito.ArgumentMatchers;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.junit.jupiter.MockitoExtension;
 
 import fr.gouv.vitamui.commons.api.domain.GroupDto;
-import fr.gouv.vitamui.commons.api.domain.ProvidedUserDto;
+import fr.gouv.vitamui.iam.common.dto.ProvidedUserDto;
 import fr.gouv.vitamui.commons.api.domain.UserDto;
-import fr.gouv.vitamui.commons.api.exception.NotFoundException;
 import fr.gouv.vitamui.commons.security.client.dto.AuthUserDto;
 import fr.gouv.vitamui.iam.common.dto.IdentityProviderDto;
 import fr.gouv.vitamui.iam.internal.server.group.service.GroupInternalService;
 import fr.gouv.vitamui.iam.internal.server.idp.service.IdentityProviderInternalService;
 import fr.gouv.vitamui.iam.internal.server.provisioning.service.ProvisioningInternalService;
+import fr.gouv.vitamui.iam.internal.server.user.dao.UserRepository;
 import fr.gouv.vitamui.iam.internal.server.user.service.UserInternalService;
 
 @ExtendWith(MockitoExtension.class)
@@ -36,6 +38,8 @@ class CasInternalServiceTest {
 
     private static final String USER_EMAIL = "user@email.test";
 
+    private static final String GROUP_ID = "groupID";
+
     @InjectMocks
     private CasInternalService casInternalService;
 
@@ -51,19 +55,20 @@ class CasInternalServiceTest {
     @Mock
     private ProvisioningInternalService provisioningInternalService;
 
+    @Mock
+    private UserRepository userRepository;
+
     @BeforeEach
     void setUp() {
         MockitoAnnotations.initMocks(this);
     }
 
-    @Test
-    void should_return_the_user_known_in_database_when_idp_auto_provisioning_is_disabled() {
-        when(identityProviderInternalService.getOne(anyString()))
-                .thenReturn(buildIDP(false));
-
+    @ParameterizedTest
+    @NullAndEmptySource
+    void should_return_the_user_known_in_database_when_idp_auto_provisioning_is_disabled(String idp) {
         when(userInternalService.findUserByEmail(USER_EMAIL)).thenReturn(buildAuthUser(false));
 
-        final UserDto user = casInternalService.getUser(USER_EMAIL, IDP, Optional.empty(), Optional.empty());
+        final UserDto user = casInternalService.getUser(USER_EMAIL, idp, null, null);
         assertThat(user).isNotNull();
     }
 
@@ -72,16 +77,17 @@ class CasInternalServiceTest {
         when(identityProviderInternalService.getOne(IDP))
                 .thenReturn(buildIDP(true));
 
-        when(provisioningInternalService.getUserInformation(USER_EMAIL, IDP, Optional.empty(), Optional.empty(), Optional.empty()))
-                .thenReturn(buildProvidedUser("RH"));
+        when(provisioningInternalService.getUserInformation(IDP, USER_EMAIL, null, null, null))
+                .thenReturn(buildProvidedUser("jean-vitam","RH"));
+
+        when(groupInternalService.getAll(any(), any())).thenReturn(List.of(buildGroup()));
 
-        when(groupInternalService.getAll(any(), any())).thenReturn(List.of(buildProfilesGroup()));
+        when(userRepository.existsByEmail(ArgumentMatchers.any())).thenReturn(false);
 
         when(userInternalService.findUserByEmail(USER_EMAIL))
-                .thenThrow(new NotFoundException("Not found"))
                 .thenReturn(buildAuthUser(false));
 
-        final UserDto user = casInternalService.getUser(USER_EMAIL, IDP, Optional.empty(), Optional.empty());
+        final UserDto user = casInternalService.getUser(USER_EMAIL, IDP, null, null);
         verify(userInternalService, times(1)).create(any());
         verify(userInternalService, times(0)).patch(any());
         assertThat(user).isNotNull();
@@ -92,15 +98,16 @@ class CasInternalServiceTest {
         when(identityProviderInternalService.getOne(IDP))
                 .thenReturn(buildIDP(true));
 
-        when(provisioningInternalService.getUserInformation(USER_EMAIL, IDP, Optional.empty(), Optional.empty(), Optional.empty()))
-                .thenReturn(buildProvidedUser("RH"));
+        when(provisioningInternalService.getUserInformation(IDP, USER_EMAIL, GROUP_ID, null, null))
+                .thenReturn(buildProvidedUser("jean vitam", "RH"));
 
-        when(groupInternalService.getAll(any(), any())).thenReturn(List.of(buildProfilesGroup()));
+        when(groupInternalService.getAll(any(), any())).thenReturn(List.of(buildGroup()));
 
+        when(userRepository.existsByEmail(ArgumentMatchers.any())).thenReturn(true);
         when(userInternalService.findUserByEmail(USER_EMAIL)).thenReturn(buildAuthUser(true));
 
 
-        final UserDto user = casInternalService.getUser(USER_EMAIL, IDP, Optional.empty(), Optional.empty());
+        final UserDto user = casInternalService.getUser(USER_EMAIL, IDP, null, null);
         verify(userInternalService, times(1)).patch(any());
         verify(userInternalService, times(0)).create(any());
         assertThat(user).isNotNull();
@@ -111,17 +118,18 @@ class CasInternalServiceTest {
         when(identityProviderInternalService.getOne(IDP))
                 .thenReturn(buildIDP(true));
 
+        when(userRepository.existsByEmail(ArgumentMatchers.any())).thenReturn(true);
         when(userInternalService.findUserByEmail(USER_EMAIL)).thenReturn(buildAuthUser(false));
 
-        final UserDto user = casInternalService.getUser(USER_EMAIL, IDP, Optional.empty(), Optional.empty());
+        final UserDto user = casInternalService.getUser(USER_EMAIL, IDP, null, null);
         verify(userInternalService, times(0)).patch(any());
         verify(userInternalService, times(0)).create(any());
         assertThat(user).isNotNull();
     }
 
-    private GroupDto buildProfilesGroup() {
+    private GroupDto buildGroup() {
         final GroupDto group = new GroupDto();
-        group.setId("Group ID");
+        group.setId(GROUP_ID);
         return group;
     }
 
@@ -131,13 +139,14 @@ class CasInternalServiceTest {
         authUser.setFirstname("Jean-Jacques");
         authUser.setLastname("Dupont");
         authUser.setAutoProvisioningEnabled(autoProvisioningEnabled);
+        authUser.setGroupId(GROUP_ID);
         return authUser;
     }
 
-    private ProvidedUserDto buildProvidedUser(final String unit) {
+    private ProvidedUserDto buildProvidedUser(final String firstName, final String unit) {
         final ProvidedUserDto providedUser = new ProvidedUserDto();
         providedUser.setEmail(USER_EMAIL);
-        providedUser.setFirstname("Jean-Jacques");
+        providedUser.setFirstname(firstName);
         providedUser.setLastname("Dupont");
         providedUser.setUnit(unit);
         return providedUser;
@@ -149,4 +158,4 @@ class CasInternalServiceTest {
         idp.setAutoProvisioningEnabled(autoProvisioningEnabled);
         return idp;
     }
-}
\ No newline at end of file
+}
diff --git a/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/provisioning/client/ProvisioningWebClientTest.java b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/provisioning/client/ProvisioningWebClientTest.java
new file mode 100644
index 000000000..1b4e9cc04
--- /dev/null
+++ b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/provisioning/client/ProvisioningWebClientTest.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020)
+ * and the signatories of the "VITAM - Accord du Contributeur" agreement.
+ * <p>
+ * contact@programmevitam.fr
+ * <p>
+ * This software is a computer program whose purpose is to implement
+ * implement a digital archiving front-office system for the secure and
+ * efficient high volumetry VITAM solution.
+ * <p>
+ * This software is governed by the CeCILL-C license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-C
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * <p>
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ * <p>
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ * <p>
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+ */
+
+package fr.gouv.vitamui.iam.internal.server.provisioning.client;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.*;
+
+import java.net.URI;
+import java.util.Optional;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import fr.gouv.vitamui.commons.rest.client.InternalHttpContext;
+import fr.gouv.vitamui.iam.common.dto.ProvidedUserDto;
+import reactor.core.publisher.Mono;
+
+@ExtendWith(MockitoExtension.class)
+class ProvisioningWebClientTest {
+
+    @InjectMocks
+    private ProvisioningWebClient provisioningWebClient;
+
+    @Mock
+    private WebClient webClientMock;
+
+    @Mock
+    private WebClient.RequestHeadersUriSpec requestHeadersUriSpecMock;
+
+    @Mock
+    private WebClient.ResponseSpec responseSpecMock;
+
+    @Mock
+    private InternalHttpContext httpContextMock;
+
+    @Test
+    void getProvidedUser_whenCalled_thenProvidedUserIsReturned() {
+        // Prepare
+        final var email = "email@toto.com";
+        ProvidedUserDto providedUserDtoStub = new ProvidedUserDto();
+        providedUserDtoStub.setEmail(email);
+
+        mockWebClientResponse(providedUserDtoStub);
+        ArgumentCaptor<URI> URICaptor = ArgumentCaptor.forClass(URI.class);
+
+        // Do
+        provisioningWebClient.getProvidedUser(httpContextMock,email,null,null,null);
+
+        // Verify
+        verify(requestHeadersUriSpecMock, times(1)).uri(URICaptor.capture());
+        URI uri = URICaptor.getValue();
+        assertThat(uri.getQuery()).contains(email);
+    }
+
+    private void mockWebClientResponse(final ProvidedUserDto providedUserDtoStub) {
+        Mono monoMock = Mockito.mock(Mono.class);
+
+        when(webClientMock.get())
+            .thenReturn(requestHeadersUriSpecMock);
+        when(requestHeadersUriSpecMock.uri(ArgumentMatchers.any(URI.class)))
+            .thenReturn(requestHeadersUriSpecMock);
+        when(requestHeadersUriSpecMock.headers(ArgumentMatchers.any()))
+            .thenReturn(requestHeadersUriSpecMock);
+        when(requestHeadersUriSpecMock.retrieve())
+            .thenReturn(responseSpecMock);
+        when(responseSpecMock.onStatus(ArgumentMatchers.any(), ArgumentMatchers.any()))
+            .thenReturn(responseSpecMock);
+        when(responseSpecMock.bodyToMono(ProvidedUserDto.class))
+            .thenReturn(monoMock);
+        when(monoMock.block())
+            .thenReturn(providedUserDtoStub);
+    }
+
+}
diff --git a/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/provisioning/service/ProvisioningInternalServiceTest.java b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/provisioning/service/ProvisioningInternalServiceTest.java
new file mode 100644
index 000000000..40a3ef964
--- /dev/null
+++ b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/provisioning/service/ProvisioningInternalServiceTest.java
@@ -0,0 +1,143 @@
+/**
+ * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020)
+ * and the signatories of the "VITAM - Accord du Contributeur" agreement.
+ * <p>
+ * contact@programmevitam.fr
+ * <p>
+ * This software is a computer program whose purpose is to implement
+ * implement a digital archiving front-office system for the secure and
+ * efficient high volumetry VITAM solution.
+ * <p>
+ * This software is governed by the CeCILL-C license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-C
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * <p>
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ * <p>
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ * <p>
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+ */
+
+package fr.gouv.vitamui.iam.internal.server.provisioning.service;
+
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+import org.junit.Assert;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import fr.gouv.vitamui.commons.api.exception.NotFoundException;
+import fr.gouv.vitamui.iam.internal.server.provisioning.config.IdPProvisioningClientConfiguration;
+import fr.gouv.vitamui.iam.internal.server.provisioning.config.ProvisioningClientConfiguration;
+import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration;
+import fr.gouv.vitamui.iam.common.dto.ProvidedUserDto;
+import fr.gouv.vitamui.iam.internal.server.provisioning.client.ProvisioningWebClient;
+import fr.gouv.vitamui.iam.security.service.InternalSecurityService;
+
+@ExtendWith(MockitoExtension.class)
+class ProvisioningInternalServiceTest {
+
+    @InjectMocks
+    private ProvisioningInternalService service;
+
+    @Mock
+    private ProvisioningClientConfiguration provisioningClientConfigurationMock;
+
+    @Mock
+    private WebClient.Builder webClientMock;
+
+    @Mock
+    private InternalSecurityService securityServiceMock;
+
+    @Nested
+    class getProvisioningClientConfiguration {
+
+        @Test
+        void whenIdpIsUnknown_NotFoundExceptionIsThrown() {
+            assertThrows(NotFoundException.class, () -> {
+                service.getProvisioningClientConfiguration("unknowIdp");
+            });
+        }
+
+        @Test
+        void whenIdpIsKnown_thenIdpIsReturned() {
+            // Prepare
+            var idpConfiguration = new IdPProvisioningClientConfiguration();
+            idpConfiguration.setIdpIdentifier("idp");
+            Mockito.when(provisioningClientConfigurationMock.getIdentityProviders()).thenReturn(Arrays.asList(idpConfiguration));
+
+            // Do
+            IdPProvisioningClientConfiguration idpFound = service.getProvisioningClientConfiguration("idp");
+
+            // Verify
+            Assert.assertEquals(idpConfiguration, idpFound);
+        }
+
+    }
+
+    @Test
+    void buildWebClient_whenCall_thenOk() {
+        // Prepare
+        var idpConfiguration = new IdPProvisioningClientConfiguration();
+        idpConfiguration.setClient(new RestClientConfiguration());
+
+        // Do
+        ProvisioningWebClient webClient = service.buildWebClient(idpConfiguration);
+
+        // Verify
+        Assert.assertNotNull(webClient);
+    }
+
+    @Test
+    void getUserInformation_whenCall_thenUserIsReturned() {
+        // Prepare
+        var provisioningInternalServiceSpy = Mockito.spy(service);
+        var provisioningWebClient = Mockito.mock(ProvisioningWebClient.class);
+        var providedUserDtoStub = new ProvidedUserDto();
+        providedUserDtoStub.setFirstname("youyou");
+
+        Mockito.doReturn(new IdPProvisioningClientConfiguration()).when(provisioningInternalServiceSpy).getProvisioningClientConfiguration(ArgumentMatchers.any());
+        Mockito.doReturn(provisioningWebClient).when(provisioningInternalServiceSpy).buildWebClient(ArgumentMatchers.any());
+        Mockito.when(provisioningWebClient.getProvidedUser(ArgumentMatchers.any(),
+            ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any())).thenReturn(providedUserDtoStub);
+
+        // Do
+        ProvidedUserDto providedUserDto =
+            provisioningInternalServiceSpy
+                .getUserInformation("idp", "email@toto.com", null, null, null);
+
+        // Verify
+        Mockito.verify(provisioningWebClient, Mockito.times(1)).getProvidedUser(ArgumentMatchers.any(),
+            ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any());
+        assertEquals(providedUserDtoStub, providedUserDto);
+    }
+}
-- 
GitLab