This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit fbc57052bfb9ab4d56b247410d992e507fd24040 Author: Benoit Tellier <[email protected]> AuthorDate: Thu Sep 26 10:33:59 2019 +0700 JAMES-2902 Write integration test for HELO SMTP hook This test aims at being used as an example for kind contributors writing tests for other SMTP hooks. --- .../mailets/configuration/SmtpConfiguration.java | 2 +- .../james/smtp/extensions/SMTPHeloHooksTest.java | 182 +++++++++++++++++++++ .../james/smtp/extensions/StaticInputChecker.java | 44 +++++ .../smtp/extensions/hooks/DeclinedHeloHook.java | 31 ++++ .../james/smtp/extensions/hooks/DenyHeloHook.java | 31 ++++ .../smtp/extensions/hooks/DenySoftHeloHook.java | 31 ++++ .../james/smtp/extensions/hooks/OkHeloHook.java | 31 ++++ .../smtp/extensions/hooks/RecordingHeloHook.java | 34 ++++ 8 files changed, 385 insertions(+), 1 deletion(-) diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/SmtpConfiguration.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/SmtpConfiguration.java index 40bcb31..3a61c48 100644 --- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/SmtpConfiguration.java +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/SmtpConfiguration.java @@ -30,12 +30,12 @@ import java.util.HashMap; import java.util.Optional; import org.apache.commons.io.IOUtils; -import org.testcontainers.shaded.com.google.common.collect.ImmutableList; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; public class SmtpConfiguration implements SerializableAsXml { public static final boolean AUTH_REQUIRED = true; diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/SMTPHeloHooksTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/SMTPHeloHooksTest.java new file mode 100644 index 0000000..3f4c984 --- /dev/null +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/SMTPHeloHooksTest.java @@ -0,0 +1,182 @@ +/**************************************************************** + * 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.smtp.extensions; + +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.awaitAtMostOneMinute; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.james.MemoryJamesServerMain; +import org.apache.james.mailets.TemporaryJamesServer; +import org.apache.james.mailets.configuration.CommonProcessors; +import org.apache.james.mailets.configuration.MailetContainer; +import org.apache.james.mailets.configuration.SmtpConfiguration; +import org.apache.james.modules.protocols.ImapGuiceProbe; +import org.apache.james.modules.protocols.SmtpGuiceProbe; +import org.apache.james.probe.DataProbe; +import org.apache.james.smtp.extensions.hooks.DeclinedHeloHook; +import org.apache.james.smtp.extensions.hooks.DenyHeloHook; +import org.apache.james.smtp.extensions.hooks.DenySoftHeloHook; +import org.apache.james.smtp.extensions.hooks.OkHeloHook; +import org.apache.james.smtp.extensions.hooks.RecordingHeloHook; +import org.apache.james.utils.DataProbeImpl; +import org.apache.james.utils.IMAPMessageReader; +import org.apache.james.utils.SMTPMessageSender; +import org.apache.james.utils.SMTPSendingException; +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class SMTPHeloHooksTest { + private static final String FROM = "fromuser@" + DEFAULT_DOMAIN; + private static final String TO = "to@" + DEFAULT_DOMAIN; + + @Rule + public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN); + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Rule + public StaticInputChecker resultChecker = new StaticInputChecker(); + @Rule + public IMAPMessageReader imapMessageReader = new IMAPMessageReader(); + + private TemporaryJamesServer jamesServer; + + private void createJamesServer(SmtpConfiguration.Builder smtpConfiguration) throws Exception { + MailetContainer.Builder mailetContainer = TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION + .putProcessor(CommonProcessors.deliverOnlyTransport()); + + jamesServer = TemporaryJamesServer.builder() + .withBase(MemoryJamesServerMain.SMTP_AND_IMAP_MODULE) + .withSmtpConfiguration(smtpConfiguration) + .withMailetContainer(mailetContainer) + .build(temporaryFolder.newFolder()); + + DataProbe dataProbe = jamesServer.getProbe(DataProbeImpl.class); + dataProbe.addDomain(DEFAULT_DOMAIN); + dataProbe.addUser(FROM, PASSWORD); + dataProbe.addUser(TO, PASSWORD); + } + + @After + public void tearDown() { + if (jamesServer != null) { + jamesServer.shutdown(); + } + } + + @Test + public void heloHookShouldBeCalledWithTheRightArgument() throws Exception { + createJamesServer(SmtpConfiguration.builder() + .addHook(RecordingHeloHook.class.getCanonicalName())); + + messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort()) + .sendMessage(FROM, TO); + + awaitAtMostOneMinute.until(() -> resultChecker.getResults().size() > 0); + assertThat(resultChecker.getResults()) + .containsExactly(Pair.of(RecordingHeloHook.class, DEFAULT_DOMAIN)); + } + + @Test + public void mailShouldBeWellDeliveredUponDeclinedHeloHook() throws Exception { + createJamesServer(SmtpConfiguration.builder() + .addHook(DeclinedHeloHook.class.getCanonicalName())); + + messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort()) + .sendMessage(FROM, TO); + + imapMessageReader.connect(LOCALHOST_IP, jamesServer.getProbe(ImapGuiceProbe.class).getImapPort()) + .login(TO, PASSWORD) + .select(IMAPMessageReader.INBOX) + .awaitMessage(awaitAtMostOneMinute); + } + + @Test + public void mailShouldBeWellDeliveredUponOKHeloHook() throws Exception { + createJamesServer(SmtpConfiguration.builder() + .addHook(OkHeloHook.class.getCanonicalName())); + + messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort()) + .sendMessage(FROM, TO); + + imapMessageReader.connect(LOCALHOST_IP, jamesServer.getProbe(ImapGuiceProbe.class).getImapPort()) + .login(TO, PASSWORD) + .select(IMAPMessageReader.INBOX) + .awaitMessage(awaitAtMostOneMinute); + } + + @Test + public void mailShouldBeWellDeliveredUponOKHeloHookFollowedByADenyHook() throws Exception { + createJamesServer(SmtpConfiguration.builder() + .addHook(OkHeloHook.class.getCanonicalName()) + .addHook(DenyHeloHook.class.getCanonicalName())); + + messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort()) + .sendMessage(FROM, TO); + + imapMessageReader.connect(LOCALHOST_IP, jamesServer.getProbe(ImapGuiceProbe.class).getImapPort()) + .login(TO, PASSWORD) + .select(IMAPMessageReader.INBOX) + .awaitMessage(awaitAtMostOneMinute); + } + + @Test + public void denyHeloHookShouldBeAppliedAfterADeclinedHeloHook() throws Exception { + createJamesServer(SmtpConfiguration.builder() + .addHook(DeclinedHeloHook.class.getCanonicalName()) + .addHook(DenyHeloHook.class.getCanonicalName())); + + messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort()); + + assertThatThrownBy(() -> messageSender.sendMessage(FROM, TO)) + .isInstanceOf(SMTPSendingException.class) + .hasMessageContaining("Error upon step Helo: 554 Email rejected"); + } + + @Test + public void smtpSessionShouldBeAbortedUponDenyHeloHook() throws Exception { + createJamesServer(SmtpConfiguration.builder() + .addHook(DenyHeloHook.class.getCanonicalName())); + + messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort()); + + assertThatThrownBy(() -> messageSender.sendMessage(FROM, TO)) + .isInstanceOf(SMTPSendingException.class) + .hasMessageContaining("Error upon step Helo: 554 Email rejected"); + } + + @Test + public void smtpSessionShouldBeAbortedUponDenySoftHeloHook() throws Exception { + createJamesServer(SmtpConfiguration.builder() + .addHook(DenySoftHeloHook.class.getCanonicalName())); + + messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort()); + + assertThatThrownBy(() -> messageSender.sendMessage(FROM, TO)) + .isInstanceOf(SMTPSendingException.class) + .hasMessageContaining("Error upon step Helo: 451 Temporary problem. Please try again later"); + } +} diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/StaticInputChecker.java b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/StaticInputChecker.java new file mode 100644 index 0000000..60f1809 --- /dev/null +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/StaticInputChecker.java @@ -0,0 +1,44 @@ +/**************************************************************** + * 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.smtp.extensions; + +import java.util.ArrayList; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.james.protocols.smtp.hook.Hook; +import org.junit.rules.ExternalResource; +import org.testcontainers.shaded.com.google.common.collect.ImmutableList; + +public class StaticInputChecker extends ExternalResource { + private static final ArrayList<Pair<Class<? extends Hook>, ?>> results = new ArrayList<>(); + + public static void registerHookResult(Class<? extends Hook> clazz, Object result) { + results.add(Pair.of(clazz, result)); + } + + @Override + protected void after() { + results.clear(); + } + + public ImmutableList<Pair<Class<? extends Hook>, ?>> getResults() { + return ImmutableList.copyOf(results); + } +} diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/DeclinedHeloHook.java b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/DeclinedHeloHook.java new file mode 100644 index 0000000..337d9d2 --- /dev/null +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/DeclinedHeloHook.java @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.smtp.extensions.hooks; + +import org.apache.james.protocols.smtp.SMTPSession; +import org.apache.james.protocols.smtp.hook.HeloHook; +import org.apache.james.protocols.smtp.hook.HookResult; + +public class DeclinedHeloHook implements HeloHook { + @Override + public HookResult doHelo(SMTPSession session, String helo) { + return HookResult.DECLINED; + } +} diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/DenyHeloHook.java b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/DenyHeloHook.java new file mode 100644 index 0000000..7d997c1 --- /dev/null +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/DenyHeloHook.java @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.smtp.extensions.hooks; + +import org.apache.james.protocols.smtp.SMTPSession; +import org.apache.james.protocols.smtp.hook.HeloHook; +import org.apache.james.protocols.smtp.hook.HookResult; + +public class DenyHeloHook implements HeloHook { + @Override + public HookResult doHelo(SMTPSession session, String helo) { + return HookResult.DENY; + } +} diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/DenySoftHeloHook.java b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/DenySoftHeloHook.java new file mode 100644 index 0000000..820224a --- /dev/null +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/DenySoftHeloHook.java @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.smtp.extensions.hooks; + +import org.apache.james.protocols.smtp.SMTPSession; +import org.apache.james.protocols.smtp.hook.HeloHook; +import org.apache.james.protocols.smtp.hook.HookResult; + +public class DenySoftHeloHook implements HeloHook { + @Override + public HookResult doHelo(SMTPSession session, String helo) { + return HookResult.DENYSOFT; + } +} diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/OkHeloHook.java b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/OkHeloHook.java new file mode 100644 index 0000000..6f24926 --- /dev/null +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/OkHeloHook.java @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.smtp.extensions.hooks; + +import org.apache.james.protocols.smtp.SMTPSession; +import org.apache.james.protocols.smtp.hook.HeloHook; +import org.apache.james.protocols.smtp.hook.HookResult; + +public class OkHeloHook implements HeloHook { + @Override + public HookResult doHelo(SMTPSession session, String helo) { + return HookResult.OK; + } +} diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/RecordingHeloHook.java b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/RecordingHeloHook.java new file mode 100644 index 0000000..a8ff118 --- /dev/null +++ b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/extensions/hooks/RecordingHeloHook.java @@ -0,0 +1,34 @@ +/**************************************************************** + * 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.smtp.extensions.hooks; + +import org.apache.james.protocols.smtp.SMTPSession; +import org.apache.james.protocols.smtp.hook.HeloHook; +import org.apache.james.protocols.smtp.hook.HookResult; +import org.apache.james.smtp.extensions.StaticInputChecker; + +public class RecordingHeloHook implements HeloHook { + @Override + public HookResult doHelo(SMTPSession session, String helo) { + HookResult result = HookResult.OK; + StaticInputChecker.registerHookResult(getClass(), helo); + return result; + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
