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]

Reply via email to