james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From btell...@apache.org
Subject [22/24] james-project git commit: JAMES-2361 implement a matcher to match Mime-Type Parameters
Date Tue, 03 Apr 2018 10:03:08 GMT
JAMES-2361 implement a matcher to match Mime-Type Parameters


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/203ad2d1
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/203ad2d1
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/203ad2d1

Branch: refs/heads/master
Commit: 203ad2d17efa4603bdf720467c5727a48d6c6f0c
Parents: b3e5088
Author: Matthieu Baechler <matthieu@apache.org>
Authored: Tue Mar 27 11:53:00 2018 +0200
Committer: benwa <btellier@linagora.com>
Committed: Tue Apr 3 17:01:38 2018 +0700

----------------------------------------------------------------------
 .../matchers/HasMimeTypeParameter.java          | 142 +++++++++++++++++
 .../matchers/HasMimeTypeParameterTest.java      | 157 +++++++++++++++++++
 2 files changed, 299 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/203ad2d1/mailet/standard/src/main/java/org/apache/james/transport/matchers/HasMimeTypeParameter.java
----------------------------------------------------------------------
diff --git a/mailet/standard/src/main/java/org/apache/james/transport/matchers/HasMimeTypeParameter.java
b/mailet/standard/src/main/java/org/apache/james/transport/matchers/HasMimeTypeParameter.java
new file mode 100644
index 0000000..bca7098
--- /dev/null
+++ b/mailet/standard/src/main/java/org/apache/james/transport/matchers/HasMimeTypeParameter.java
@@ -0,0 +1,142 @@
+/****************************************************************
+ * 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.matchers;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.activation.MimeType;
+import javax.activation.MimeTypeParseException;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.core.MailAddress;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailetException;
+import org.apache.mailet.base.GenericMatcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.fge.lambdas.Throwing;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+
+
+/**
+ * <p>This matcher checks if the content type parameters matches.</p>
+ *
+ * use: <pre>
+ *     <code>
+ *         <mailet match="HasMimeTypeParameter=report-type=disposition-notification,report-type=other"
class="..." />
+ *     </code>
+ * </pre>
+ */
+public class HasMimeTypeParameter extends GenericMatcher {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(HasMimeTypeParameter.class);
+
+    @VisibleForTesting List<Pair<String, String>> filteredMimeTypeParameters;
+
+    @Override
+    public void init() throws MessagingException {
+        filteredMimeTypeParameters = parseConfigurationString(Optional.ofNullable(getCondition()));
+    }
+
+    private List<Pair<String, String>> parseConfigurationString(Optional<String>
maybeConfiguration) {
+        return maybeConfiguration
+            .map(tokenizeConfiguration())
+            .orElse(ImmutableList.of());
+    }
+
+    private Function<String, List<Pair<String, String>>> tokenizeConfiguration()
{
+        return Throwing.<String, List<Pair<String, String>>>function(
+            value -> {
+                try {
+                    return Splitter.on(",")
+                        .trimResults()
+                        .splitToList(value)
+                        .stream()
+                        .map(this::conditionToPair)
+                        .collect(Guavate.toImmutableList());
+                } catch (IllegalArgumentException e) {
+                    throw new MailetException("error parsing configuration", e);
+                }
+            }
+        ).sneakyThrow();
+    }
+
+    private Pair<String, String> conditionToPair(String s) {
+        Preconditions.checkArgument(s.contains("="));
+        List<String> pairElements = Splitter.on("=")
+            .limit(2)
+            .splitToList(s);
+        validateCondition(pairElements);
+
+        return Pair.of(pairElements.get(0), unQuote(pairElements.get(1)));
+    }
+
+    private void validateCondition(List<String> pairElements) {
+        Preconditions.checkArgument(pairElements.stream().noneMatch(Strings::isNullOrEmpty),
+            "Empty name or value for the parameter argument");
+    }
+
+    private String unQuote(String value) {
+        return StringUtils.unwrap(value, '"');
+    }
+
+    @Override
+    public Collection<MailAddress> match(Mail mail) throws MessagingException {
+        Optional<MimeType> maybeMimeType = getMimeTypeFromMessage(mail.getMessage());
+        if (maybeMimeType.map(this::mimeTypeMatchParameter).orElse(false)) {
+            return mail.getRecipients();
+        }
+        return ImmutableList.of();
+    }
+
+    private Optional<MimeType> getMimeTypeFromMessage(MimeMessage message) throws MessagingException
{
+        try {
+            return Optional.of(new MimeType(message.getContentType()));
+        } catch (MimeTypeParseException e) {
+            LOGGER.warn("Error while parsing message's mimeType {}", message.getContentType(),
e);
+            return Optional.empty();
+        }
+    }
+
+    private boolean mimeTypeMatchParameter(MimeType mimeType) {
+        return filteredMimeTypeParameters
+            .stream()
+            .anyMatch(entry -> mimeTypeContainsParameter(mimeType, entry.getKey(), entry.getValue()));
+    }
+
+    private boolean mimeTypeContainsParameter(MimeType mimeType, String name, String value)
{
+        return Optional.ofNullable(mimeType.getParameter(name)).map(value::equals).orElse(false);
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/james-project/blob/203ad2d1/mailet/standard/src/test/java/org/apache/james/transport/matchers/HasMimeTypeParameterTest.java
----------------------------------------------------------------------
diff --git a/mailet/standard/src/test/java/org/apache/james/transport/matchers/HasMimeTypeParameterTest.java
b/mailet/standard/src/test/java/org/apache/james/transport/matchers/HasMimeTypeParameterTest.java
new file mode 100644
index 0000000..3817f44
--- /dev/null
+++ b/mailet/standard/src/test/java/org/apache/james/transport/matchers/HasMimeTypeParameterTest.java
@@ -0,0 +1,157 @@
+/****************************************************************
+ * 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.matchers;
+
+import static org.apache.mailet.base.MailAddressFixture.RECIPIENT1;
+import static org.apache.mailet.base.MailAddressFixture.SENDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import javax.mail.MessagingException;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.core.builder.MimeMessageBuilder;
+import org.apache.mailet.MailetException;
+import org.apache.mailet.base.test.FakeMail;
+import org.apache.mailet.base.test.FakeMatcherConfig;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class HasMimeTypeParameterTest {
+
+    private static final String TEST_CONTENT_TYPE = "multipart/report; report-type=\"disposition-notification\";
boundary=\"=-ac61K8KXSRpaQ/eveStc\"";
+
+    private HasMimeTypeParameter matcher;
+    private FakeMail sampleMail;
+
+    @BeforeEach
+    void setUp() throws MessagingException {
+        matcher = new HasMimeTypeParameter();
+        sampleMail = FakeMail.builder()
+            .mimeMessage(MimeMessageBuilder
+                .mimeMessageBuilder()
+                .setSubject("Mail read")
+                .addHeader("Content-Type", TEST_CONTENT_TYPE)
+                .setText("You email has been read by Bart", TEST_CONTENT_TYPE))
+            .sender(SENDER)
+            .recipient(RECIPIENT1)
+            .build();
+    }
+
+    @Test
+    void shouldThrowWhenConditionHasNoEquals() {
+        assertThatThrownBy(() ->
+            matcher.init(FakeMatcherConfig.builder()
+                .matcherName("HasMimeType")
+                .condition("abc")
+                .build()))
+            .isInstanceOf(MailetException.class);
+    }
+
+    @Test
+    void shouldThrowWhenConditionHasNoValue() {
+        assertThatThrownBy(() ->
+            matcher.init(FakeMatcherConfig.builder()
+                .matcherName("HasMimeType")
+                .condition("abc=")
+                .build()))
+            .isInstanceOf(MailetException.class);
+    }
+
+
+    @Test
+    void shouldThrowWhenConditionHasNoName() {
+        assertThatThrownBy(() ->
+            matcher.init(FakeMatcherConfig.builder()
+                .matcherName("HasMimeType")
+                .condition("=abc")
+                .build()))
+            .isInstanceOf(MailetException.class);
+    }
+
+    @Test
+    void shouldSupportEqualsInValue() throws MessagingException {
+        matcher.init(FakeMatcherConfig.builder()
+            .matcherName("HasMimeType")
+            .condition("abc=123,def==--")
+            .build());
+        assertThat(matcher.filteredMimeTypeParameters).contains(Pair.of("def", "=--"));
+    }
+
+    @Test
+    void shouldMatchNothingWhenNoCondition() throws MessagingException {
+        matcher.init(FakeMatcherConfig.builder()
+            .matcherName("HasMimeType")
+            .build());
+
+        assertThat(matcher.match(sampleMail)).isEmpty();
+    }
+
+    @Test
+    void shouldNotMatchWhenConditionNotFulfilled() throws MessagingException {
+        matcher.init(FakeMatcherConfig.builder()
+            .matcherName("HasMimeType")
+            .condition("no-entry=for-that")
+            .build());
+
+        assertThat(matcher.match(sampleMail)).isEmpty();
+    }
+
+    @Test
+    void shouldMatchReportType() throws MessagingException {
+        matcher.init(FakeMatcherConfig.builder()
+            .matcherName("HasMimeType")
+            .condition("report-type=\"disposition-notification\"")
+            .build());
+
+        assertThat(matcher.match(sampleMail)).contains(RECIPIENT1);
+    }
+
+    @Test
+    void shouldMatchAnyConfigurationCondition() throws MessagingException {
+        matcher.init(FakeMatcherConfig.builder()
+            .matcherName("HasMimeType")
+            .condition("report-type=\"not found\",boundary=\"=-ac61K8KXSRpaQ/eveStc\"")
+            .build());
+
+        assertThat(matcher.match(sampleMail)).contains(RECIPIENT1);
+    }
+
+    @Test
+    void shouldMatchConditionWithSameKey() throws MessagingException {
+        matcher.init(FakeMatcherConfig.builder()
+            .matcherName("HasMimeType")
+            .condition("report-type=\"not found\",report-type=\"disposition-notification\"")
+            .build());
+
+        assertThat(matcher.match(sampleMail)).contains(RECIPIENT1);
+    }
+
+    @Test
+    void shouldMatchReportTypeEvenWithoutQuotaInConfiguration() throws MessagingException
{
+        matcher.init(FakeMatcherConfig.builder()
+            .matcherName("HasMimeType")
+            .condition("report-type=disposition-notification")
+            .build());
+
+        assertThat(matcher.match(sampleMail)).contains(RECIPIENT1);
+    }
+
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message