JAMES-2341 Tell to SpamAssassin spam message
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/2b62f545 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/2b62f545 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/2b62f545 Branch: refs/heads/master Commit: 2b62f54597f356dbc06a8b376d89c945e7af13b4 Parents: 2798ed9 Author: Antoine Duprat <[email protected]> Authored: Tue Feb 27 15:29:43 2018 +0100 Committer: Antoine Duprat <[email protected]> Committed: Thu Mar 8 10:36:33 2018 +0100 ---------------------------------------------------------------------- .../james/util/scanner/SpamAssassinInvoker.java | 50 +++++++++++++++++++- .../util/scanner/SpamAssassinExtension.java | 2 +- .../util/scanner/SpamAssassinInvokerTest.java | 22 +++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/2b62f545/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java ---------------------------------------------------------------------- diff --git a/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java b/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java index c9429e9..95063da 100644 --- a/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java +++ b/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java @@ -21,6 +21,7 @@ package org.apache.james.util.scanner; import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; @@ -31,6 +32,8 @@ import java.util.List; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; +import org.apache.commons.io.IOUtils; + import com.google.common.base.Splitter; import com.google.common.collect.Lists; @@ -49,6 +52,7 @@ public class SpamAssassinInvoker { private static final int SPAM_INDEX = 1; private static final int HITS_INDEX = 3; private static final int REQUIRED_HITS_INDEX = 5; + private static final String CRLF = "\r\n"; private final String spamdHost; @@ -82,7 +86,9 @@ public class SpamAssassinInvoker { PrintWriter writer = new PrintWriter(out); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { - writer.write("CHECK SPAMC/1.2\r\n\r\n"); + writer.write("CHECK SPAMC/1.2"); + writer.write(CRLF); + writer.write(CRLF); writer.flush(); // pass the message to spamd @@ -132,4 +138,46 @@ public class SpamAssassinInvoker { private boolean isSpam(String line) { return line.startsWith("Spam:"); } + + /** + * Tell spamd that the given MimeMessage is a spam. + * + * @param message + * The MimeMessage to tell + * @throws MessagingException + * if an error occured during learning. + */ + public boolean learnAsSpam(InputStream message) throws MessagingException { + try (Socket socket = new Socket(spamdHost, spamdPort); + OutputStream out = socket.getOutputStream(); + PrintWriter writer = new PrintWriter(out); + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { + + writer.write("TELL SPAMC/1.2"); + writer.write(CRLF); + writer.write("Message-class: spam"); + writer.write(CRLF); + writer.write("Set: local, remote"); + writer.write(CRLF); + writer.write(CRLF); + writer.flush(); + + IOUtils.copy(message, out); + out.flush(); + socket.shutdownOutput(); + + return in.lines() + .filter(this::hasBeenSet) + .findAny() + .isPresent(); + } catch (UnknownHostException e) { + throw new MessagingException("Error communicating with spamd. Unknown host: " + spamdHost); + } catch (IOException e) { + throw new MessagingException("Error communicating with spamd on " + spamdHost + ":" + spamdPort + " Exception: " + e); + } + } + + private boolean hasBeenSet(String line) { + return line.startsWith("DidSet"); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/2b62f545/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinExtension.java ---------------------------------------------------------------------- diff --git a/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinExtension.java b/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinExtension.java index 5f4530e..c185be6 100644 --- a/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinExtension.java +++ b/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinExtension.java @@ -48,7 +48,7 @@ public class SpamAssassinExtension implements BeforeAllCallback, AfterAllCallbac private SpamAssassin spamAssassin; public SpamAssassinExtension() { - spamAssassinContainer = new GenericContainer<>("dinkel/spamassassin:3.4.0"); + spamAssassinContainer = new GenericContainer<>("aduprat/spamassassin:latest"); spamAssassinContainer.waitingFor(new SpamAssassinWaitStrategy()); } http://git-wip-us.apache.org/repos/asf/james-project/blob/2b62f545/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java ---------------------------------------------------------------------- diff --git a/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java b/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java index 3e3fd4b..fdf3b83 100644 --- a/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java +++ b/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java @@ -79,4 +79,26 @@ public class SpamAssassinInvokerTest { assertThat(result.getHeadersAsAttribute().get(SpamAssassinInvoker.FLAG_MAIL_ATTRIBUTE_NAME)).isEqualTo("YES"); } + + @Test + public void learnAsSpamShouldReturnTrueWhenLearningWorks() throws Exception { + MimeMessage mimeMessage = MimeMessageUtil.mimeMessageFromStream( + ClassLoader.getSystemResourceAsStream("spamassassin_db/spam/spam1")); + + boolean result = testee.learnAsSpam(mimeMessage.getInputStream()); + + assertThat(result).isTrue(); + } + + @Test + public void scanMailShouldMarkHasSpamWhenMessageAlreadyLearnedAsSpam() throws Exception { + MimeMessage mimeMessage = MimeMessageUtil.mimeMessageFromStream( + ClassLoader.getSystemResourceAsStream("spamassassin_db/spam/spam1")); + + testee.learnAsSpam(mimeMessage.getInputStream()); + + SpamAssassinResult result = testee.scanMail(mimeMessage); + + assertThat(result.getHeadersAsAttribute().get(SpamAssassinInvoker.FLAG_MAIL_ATTRIBUTE_NAME)).isEqualTo("YES"); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
