diff --git a/README.md b/README.md
index 371553e..1a478dd 100644
--- a/README.md
+++ b/README.md
@@ -142,6 +142,10 @@ The pivot used for the synchronization in the LSC connector is the email address
The destination attributes for the LSC aliases connector are named `firstname` and `surname`.
+For the domain synchronization, you can specify the wished domain list to be synchronized by specify the dedicated ENV variable with key `DOMAIN_LIST_TO_SYNCHRONIZE` and DELIMITER `,`. The synchronization for other domain contacts will be ignored (no create, update, delete operation). For example: `DOMAIN_LIST_TO_SYNCHRONIZE=james.org,linagora.com`.
+
+If you omit this environment variable setting, all domains contact will be synchronized from LDAP.
+
### Address Mappings Synchronization
For example, it can be used to synchronize the address mappings stored in the LDAP server to the TMail Server(s) of a TMail deployment.
@@ -326,7 +330,8 @@ The values to configure are:
The domains used in the aliases must have been previously created in TMail.
Otherwise, if a user have a single alias pointing to an unknown domain, none of her aliases will be added.
-For the domain synchronization, you can specify the wished domain list to be synchronized by specify the dedicated ENV variable with key `DOMAIN_LIST_TO_SYNCHRONIZE` and DELIMITER `,`.
+For the domain synchronization, you can specify the wished domain list to be synchronized by specify the dedicated ENV variable with key `DOMAIN_LIST_TO_SYNCHRONIZE` and DELIMITER `,`. The synchronization for other domain contacts will be ignored (no create, update, delete operation). For example: `DOMAIN_LIST_TO_SYNCHRONIZE=linagora.com` or `DOMAIN_LIST_TO_SYNCHRONIZE=lists.linagora.com`.
+
If you omit this environment variable setting, all domains contact will be synchronized from LDAP.
The jar of the TMail LSC plugin (`target/lsc-tmail-plugin-1.0-distribution.jar`) must be copied in the `lib` directory of your LSC installation.
diff --git a/sample/ldap-to-tmail-contact/lsc.xml b/sample/ldap-to-tmail-contact/lsc.xml
index 6cf9781..b732e22 100644
--- a/sample/ldap-to-tmail-contact/lsc.xml
+++ b/sample/ldap-to-tmail-contact/lsc.xml
@@ -62,7 +62,7 @@
true
true
- false
+ true
false
diff --git a/src/main/java/org/lsc/plugins/connectors/james/TMailContactDstService.java b/src/main/java/org/lsc/plugins/connectors/james/TMailContactDstService.java
index a4b3486..44872d9 100644
--- a/src/main/java/org/lsc/plugins/connectors/james/TMailContactDstService.java
+++ b/src/main/java/org/lsc/plugins/connectors/james/TMailContactDstService.java
@@ -78,6 +78,9 @@ public boolean apply(LscModifications lscModifications) throws LscServiceExcepti
} else {
return false;
}
+ case DELETE_OBJECT:
+ LOGGER.debug("Domain contact {} exists on TMail but not in LDAP. Deleting this domain contact.", email);
+ return jamesDao.removeDomainContact(email);
default:
LOGGER.debug("{} operation, ignored.", lscModifications.getOperation());
return false;
diff --git a/src/test/java/org/lsc/plugins/connectors/james/TMailContactDstServiceTest.java b/src/test/java/org/lsc/plugins/connectors/james/TMailContactDstServiceTest.java
index 8871027..79df37a 100644
--- a/src/test/java/org/lsc/plugins/connectors/james/TMailContactDstServiceTest.java
+++ b/src/test/java/org/lsc/plugins/connectors/james/TMailContactDstServiceTest.java
@@ -4,6 +4,7 @@
import static io.restassured.config.EncoderConfig.encoderConfig;
import static io.restassured.config.RestAssuredConfig.newConfig;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.SoftAssertions.assertSoftly;
import static org.hamcrest.Matchers.hasSize;
import static org.lsc.plugins.connectors.james.TMailContactDstService.EMAIL_KEY;
@@ -27,6 +28,8 @@
import java.util.Map;
import java.util.Optional;
+import javax.ws.rs.NotFoundException;
+
import org.apache.http.HttpStatus;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
@@ -307,6 +310,78 @@ void shouldSupportPartialUpdate() throws Exception {
CONTACT_RENE.getFirstname(), Optional.of("Surname")));
}
+ @Test
+ void deleteOperationShouldDeleteDomainContactWhenUserDoesNotExistAnymoreOnLDAP() throws Exception {
+ createContact(CONTACT_RENE);
+
+ LscModifications modifications = new LscModifications(LscModificationType.DELETE_OBJECT);
+ modifications.setMainIdentifer(CONTACT_RENE.getEmailAddress());
+ modifications.setLscAttributeModifications(ImmutableList.of());
+
+ boolean applied = testee.apply(modifications);
+
+ assertThat(applied).isTrue();
+ assertNonExistingDomainContact(CONTACT_RENE.getEmailAddress());
+ }
+
+ @Test
+ void deleteOperationShouldNotDeleteContactsOfOtherUsers() throws Exception {
+ createContact(CONTACT_RENE);
+ createContact(CONTACT_TUNG);
+
+ // delete contact of Tung
+ LscModifications modifications = new LscModifications(LscModificationType.DELETE_OBJECT);
+ modifications.setMainIdentifer(CONTACT_TUNG.getEmailAddress());
+ modifications.setLscAttributeModifications(ImmutableList.of());
+
+ boolean applied = testee.apply(modifications);
+
+ // contact of Tung should be deleted, but not contact of Rene
+ assertThat(applied).isTrue();
+ assertNonExistingDomainContact(CONTACT_TUNG.getEmailAddress());
+ assertThat(jamesDao.getContact(CONTACT_RENE.getEmailAddress()))
+ .isEqualTo(new Contact(CONTACT_RENE.getEmailAddress(), CONTACT_RENE.getFirstname(), CONTACT_RENE.getSurname()));
+ }
+
+ @Test
+ void deleteOperationWouldDeleteContactsOfUnwishedDomainByDefault() throws Exception {
+ // If we do not configure the DOMAIN_LIST_TO_SYNCHRONIZE which means we synchronize all domains by default
+ forceSynchronizeDomainListValue(Optional.empty());
+ createContact(CONTACT_RENE);
+ createContact(CONTACT_WITH_UN_WISHED_DOMAIN);
+
+ // Assume unwished domain entry does not exist in filtered LDAP baseDN of james.org domain
+ LscModifications modifications = new LscModifications(LscModificationType.DELETE_OBJECT);
+ modifications.setMainIdentifer(CONTACT_WITH_UN_WISHED_DOMAIN.getEmailAddress());
+ modifications.setLscAttributeModifications(ImmutableList.of());
+
+ boolean applied = testee.apply(modifications);
+
+ // then unwished domain contact would be deleted
+ assertThat(applied).isTrue();
+ assertNonExistingDomainContact(CONTACT_WITH_UN_WISHED_DOMAIN.getEmailAddress());
+ }
+
+ @Test
+ void deleteShouldNotDeleteContactsOfUnwishedDomainWhenConfigured() throws Exception {
+ // Only synchronize james.org domain, ignore other domains (e.g. unwisheddomain.org)
+ forceSynchronizeDomainListValue(Arrays.asList("james.org"));
+ createContact(CONTACT_RENE);
+ createContact(CONTACT_WITH_UN_WISHED_DOMAIN);
+
+ // Assume unwished domain entry does not exist in filtered LDAP baseDN of james.org domain
+ LscModifications modifications = new LscModifications(LscModificationType.DELETE_OBJECT);
+ modifications.setMainIdentifer(CONTACT_WITH_UN_WISHED_DOMAIN.getEmailAddress());
+ modifications.setLscAttributeModifications(ImmutableList.of());
+
+ boolean applied = testee.apply(modifications);
+
+ // then unwished domain contact should not be deleted
+ assertThat(applied).isFalse();
+ assertThat(jamesDao.getContact(CONTACT_WITH_UN_WISHED_DOMAIN.getEmailAddress()))
+ .isEqualTo(new Contact(CONTACT_WITH_UN_WISHED_DOMAIN.getEmailAddress(), CONTACT_WITH_UN_WISHED_DOMAIN.getFirstname(), CONTACT_WITH_UN_WISHED_DOMAIN.getSurname()));
+ }
+
@Test
void getBeanShouldReturnNullWhenEmptyDataset() throws Exception {
assertThat(testee.getBean("email", new LscDatasets(), FROM_SAME_SERVICE)).isNull();
@@ -367,12 +442,21 @@ private void createContact(Contact contact) throws JsonProcessingException {
}
// using reflection to change DOMAIN_LIST_TO_SYNCHRONIZE value
- private static void forceSynchronizeDomainListValue(List domainList) throws NoSuchFieldException, IllegalAccessException {
+ private static void forceSynchronizeDomainListValue(Optional> domainListOptional) throws NoSuchFieldException, IllegalAccessException {
final Field field = SyncContactConfig.class.getDeclaredField("DOMAIN_LIST_TO_SYNCHRONIZE");
field.setAccessible(true);
final Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
- field.set(null, Optional.of(domainList));
+ field.set(null, domainListOptional);
+ }
+
+ private static void forceSynchronizeDomainListValue(List domainList) throws NoSuchFieldException, IllegalAccessException {
+ forceSynchronizeDomainListValue(Optional.of(domainList));
+ }
+
+ private void assertNonExistingDomainContact(String email) {
+ assertThatThrownBy(() -> jamesDao.getContact(email))
+ .isInstanceOf(NotFoundException.class);
}
}