JAMES-2413 [DLP] Mailet to store an email in a repository depending on the domain of the sender
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/adfcf46d Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/adfcf46d Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/adfcf46d Branch: refs/heads/master Commit: adfcf46d62be5c2eb5e2a174123ae40dbb12349b Parents: ca761df Author: duc <trantiendu...@gmail.com> Authored: Wed Jun 6 16:55:06 2018 +0700 Committer: benwa <btell...@linagora.com> Committed: Wed Jun 13 09:42:35 2018 +0700 ---------------------------------------------------------------------- .../mailets/ToSenderDomainRepositoryTest.java | 102 ++++++++++ server/mailet/mailets/pom.xml | 31 ++- .../mailets/ToSenderDomainRepository.java | 89 +++++++++ .../mailets/ToSenderDomainRepositoryTest.java | 195 +++++++++++++++++++ 4 files changed, 412 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/adfcf46d/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java ---------------------------------------------------------------------- diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java new file mode 100644 index 0000000..1e19e08 --- /dev/null +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java @@ -0,0 +1,102 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.transport.mailets; + +import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN; +import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP; +import static org.apache.james.mailets.configuration.Constants.PASSWORD; +import static org.apache.james.mailets.configuration.Constants.SMTP_PORT; +import static org.apache.james.mailets.configuration.Constants.awaitAtMostOneMinute; + +import org.apache.james.mailets.TemporaryJamesServer; +import org.apache.james.mailets.configuration.MailetConfiguration; +import org.apache.james.mailets.configuration.MailetContainer; +import org.apache.james.mailets.configuration.ProcessorConfiguration; +import org.apache.james.probe.DataProbe; +import org.apache.james.transport.matchers.All; +import org.apache.james.utils.DataProbeImpl; +import org.apache.james.utils.IMAPMessageReader; +import org.apache.james.utils.MailRepositoryProbeImpl; +import org.apache.james.utils.SMTPMessageSender; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class ToSenderDomainRepositoryTest { + + private static final String RECIPIENT = "touser@" + DEFAULT_DOMAIN; + private static final String CUSTOM_REPOSITORY_PREFIX = "file://var/mail/custom/"; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Rule + public IMAPMessageReader imapMessageReader = new IMAPMessageReader(); + @Rule + public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN); + + private TemporaryJamesServer jamesServer; + private MailRepositoryProbeImpl probe; + + @Before + public void setup() throws Exception { + MailetContainer.Builder mailetContainer = TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION + .putProcessor(ProcessorConfiguration.root() + .addMailet(MailetConfiguration.builder() + .matcher(All.class) + .mailet(ToSenderDomainRepository.class) + .addProperty("urlPrefix", CUSTOM_REPOSITORY_PREFIX))); + + jamesServer = TemporaryJamesServer.builder() + .withMailetContainer(mailetContainer) + .build(temporaryFolder); + + DataProbe dataProbe = jamesServer.getProbe(DataProbeImpl.class); + dataProbe.addDomain(DEFAULT_DOMAIN); + dataProbe.addUser(RECIPIENT, PASSWORD); + + probe = jamesServer.getProbe(MailRepositoryProbeImpl.class); + } + + @After + public void tearDown() { + jamesServer.shutdown(); + } + + @Test + public void incomingMailShouldBeStoredInCorrespondingMailRepository() throws Exception { + messageSender.connect(LOCALHOST_IP, SMTP_PORT) + .sendMessage(RECIPIENT, RECIPIENT); + + awaitAtMostOneMinute.until( + () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 1); + } + + @Test + public void incomingMailsShouldBeStoredInCorrespondingMailRepository() throws Exception { + messageSender.connect(LOCALHOST_IP, SMTP_PORT) + .sendMessage(RECIPIENT, RECIPIENT) + .sendMessage(RECIPIENT, RECIPIENT); + + awaitAtMostOneMinute.until( + () -> probe.getRepositoryMailCount(CUSTOM_REPOSITORY_PREFIX + DEFAULT_DOMAIN) == 2); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/adfcf46d/server/mailet/mailets/pom.xml ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/pom.xml b/server/mailet/mailets/pom.xml index fdbe73a..eb72017 100644 --- a/server/mailet/mailets/pom.xml +++ b/server/mailet/mailets/pom.xml @@ -113,6 +113,12 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>james-server-data-library</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>james-server-data-memory</artifactId> <scope>test</scope> </dependency> @@ -140,6 +146,11 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>james-server-mailrepository-memory</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>james-server-queue-api</artifactId> </dependency> <dependency> @@ -192,11 +203,6 @@ <artifactId>joda-time</artifactId> </dependency> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> @@ -230,6 +236,21 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-launcher</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> http://git-wip-us.apache.org/repos/asf/james-project/blob/adfcf46d/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java new file mode 100644 index 0000000..b86482e --- /dev/null +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java @@ -0,0 +1,89 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.transport.mailets; + +import java.util.Optional; + +import javax.inject.Inject; +import javax.mail.MessagingException; + +import org.apache.james.mailrepository.api.MailRepositoryStore; +import org.apache.mailet.Mail; +import org.apache.mailet.base.GenericMailet; + +/** + * Stores incoming Mail in a repository defined by the sender's domain.<br> + * + * Supported configuration parameters: + * + * - "urlPrefix" mandatory: defines the prefix for the per sender's domain repository. + * For example for the value 'cassandra://var/mail/sendersRepositories/', a mail sent by 'u...@james.org' + * will be stored in 'cassandra://var/mail/sendersRepositories/james.org'. + * - "passThrough" optional, defaults to false. If true, the processing of the mail continues. If false it stops. + * + * Example: + * + * <mailet matcher="All" class="ToSenderDomainRepository"> + * <urlPrefix>cassandra://var/mail/sendersRepositories/</urlPrefix> + * <passThrough>false</passThrough> + * </mailet> + */ +public class ToSenderDomainRepository extends GenericMailet { + + private static final boolean DEFAULT_CONSUME = false; + + private final MailRepositoryStore mailRepositoryStore; + private String urlPrefix; + private boolean passThrough; + + @Inject + public ToSenderDomainRepository(MailRepositoryStore mailRepositoryStore) { + this.mailRepositoryStore = mailRepositoryStore; + } + + @Override + public void init() throws MessagingException { + urlPrefix = Optional.ofNullable(getInitParameter("urlPrefix")) + .orElseThrow(() -> new MessagingException("'urlPrefix' is a mandatory configuration property")); + passThrough = getInitParameter("passThrough", DEFAULT_CONSUME); + } + + @Override + public void service(Mail mail) throws MessagingException { + String url = urlPrefix + mail.getSender().getDomain().asString(); + store(mail, url); + if (!passThrough) { + mail.setState(Mail.GHOST); + } + } + + private void store(Mail mail, String url) throws MessagingException { + try { + mailRepositoryStore.select(url).store(mail); + } catch (MailRepositoryStore.MailRepositoryStoreException e) { + throw new MessagingException("Error while selecting url " + url, e); + } + } + + @Override + public String getMailetInfo() { + return "ToSenderDomainRepository Mailet"; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/adfcf46d/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java new file mode 100644 index 0000000..e532e90 --- /dev/null +++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/ToSenderDomainRepositoryTest.java @@ -0,0 +1,195 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.transport.mailets; + +import static org.apache.mailet.base.MailAddressFixture.JAMES_LOCAL; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import javax.mail.MessagingException; + +import org.apache.james.mailrepository.api.MailRepository; +import org.apache.james.mailrepository.api.MailRepositoryStore; +import org.apache.james.mailrepository.memory.MemoryMailRepository; +import org.apache.james.mailrepository.mock.MockMailRepositoryStore; +import org.apache.mailet.Mail; +import org.apache.mailet.base.MailAddressFixture; +import org.apache.mailet.base.test.FakeMail; +import org.apache.mailet.base.test.FakeMailetConfig; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ToSenderDomainRepositoryTest { + + private static final FakeMailetConfig DEFAULT_MAILET_CONFIG = FakeMailetConfig.builder() + .mailetName("TestConfig") + .setProperty("urlPrefix", "memory://var/mail/dlp/") + .build(); + private ToSenderDomainRepository mailet; + private MockMailRepositoryStore mailRepositoryStore; + + @BeforeEach + void setup() { + mailRepositoryStore = new MockMailRepositoryStore(); + mailRepositoryStore.add("memory://var/mail/dlp/" + JAMES_LOCAL, new MemoryMailRepository()); + mailet = new ToSenderDomainRepository(mailRepositoryStore); + } + + @Test + void initShouldThrowExceptionWhenUrlPrefixIsAbsent() { + FakeMailetConfig mailetConfig = FakeMailetConfig.builder() + .mailetName("Test") + .build(); + + assertThatThrownBy(() -> mailet.init(mailetConfig)) + .isInstanceOf(MessagingException.class); + } + + @Test + void initShouldNotThrowWhenUrlPrefixIsPresent() throws MessagingException { + mailet.init(DEFAULT_MAILET_CONFIG); + } + + @Test + void serviceShouldStoreMailInRepository() throws Exception { + mailet.init(DEFAULT_MAILET_CONFIG); + + String mailName = "mailName"; + mailet.service(FakeMail.builder() + .name(mailName) + .sender(MailAddressFixture.SENDER) + .build()); + + MailRepository mailRepository = mailRepositoryStore.select("memory://var/mail/dlp/" + JAMES_LOCAL); + + assertThat(mailRepository.list()) + .extracting(mailRepository::retrieve) + .extracting(Mail::getName) + .containsOnly(mailName); + } + + @Test + void serviceShouldGhostMailWhenNotPassThrough() throws Exception { + FakeMailetConfig mailetConfig = FakeMailetConfig.builder() + .mailetName("TestConfig") + .setProperty("passThrough", "false") + .setProperty("urlPrefix", "memory://var/mail/dlp/") + .build(); + mailet.init(mailetConfig); + + FakeMail mail = FakeMail.builder() + .name("mailName") + .sender(MailAddressFixture.SENDER) + .state(Mail.DEFAULT) + .build(); + + mailet.service(mail); + + assertThat(mail.getState()) + .isEqualTo(Mail.GHOST); + } + + @Test + void serviceShouldPreserveMailStateWhenPassThrough() throws Exception { + FakeMailetConfig mailetConfig = FakeMailetConfig.builder() + .mailetName("TestConfig") + .setProperty("passThrough", "true") + .setProperty("urlPrefix", "memory://var/mail/dlp/") + .build(); + mailet.init(mailetConfig); + + FakeMail mail = FakeMail.builder() + .name("mailName") + .sender(MailAddressFixture.SENDER) + .state(Mail.DEFAULT) + .build(); + + mailet.service(mail); + + assertThat(mail.getState()) + .isEqualTo(Mail.DEFAULT); + } + + @Test + void passThroughShouldDefaultToFalse() throws Exception { + mailet.init(DEFAULT_MAILET_CONFIG); + + FakeMail mail = FakeMail.builder() + .name("mailName") + .sender(MailAddressFixture.SENDER) + .state(Mail.DEFAULT) + .build(); + + mailet.service(mail); + + assertThat(mail.getState()) + .isEqualTo(Mail.GHOST); + } + + @Test + void initShouldSetNotPassThroughWhenPassThroughIsNotSet() throws Exception { + MailRepositoryStore mailRepositoryStore = mock(MailRepositoryStore.class); + ToSenderDomainRepository mailet = new ToSenderDomainRepository(mailRepositoryStore); + when(mailRepositoryStore.select(any())) + .thenThrow(new MailRepositoryStore.MailRepositoryStoreException("any")); + + mailet.init(DEFAULT_MAILET_CONFIG); + + FakeMail mail = FakeMail.builder() + .name("mailName") + .sender(MailAddressFixture.SENDER) + .state(Mail.DEFAULT) + .build(); + + assertThatThrownBy(() -> mailet.service(mail)) + .isInstanceOf(MessagingException.class); + } + + @Test + void initShouldSetNotPassThroughWhenPassThroughIsNotBoolean() throws Exception { + FakeMailetConfig mailetConfig = FakeMailetConfig.builder() + .mailetName("TestConfig") + .setProperty("urlPrefix", "memory://var/mail/dlp/") + .setProperty("passThrough", "not boolean") + .build(); + + mailet.init(mailetConfig); + + FakeMail mail = FakeMail.builder() + .name("mailName") + .sender(MailAddressFixture.SENDER) + .state(Mail.DEFAULT) + .build(); + + mailet.service(mail); + + assertThat(mail.getState()) + .isEqualTo(Mail.GHOST); + } + + @Test + void getMailetInfoShouldReturnExpectedResult() { + assertThat(mailet.getMailetInfo()) + .isEqualTo("ToSenderDomainRepository Mailet"); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org