You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ad...@apache.org on 2018/08/30 13:15:43 UTC
[01/26] james-project git commit: JAMES-2529 Mailet Filter
implementation
Repository: james-project
Updated Branches:
refs/heads/master 1968a528f -> 072feaca6
JAMES-2529 Mailet Filter implementation
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/897cb08c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/897cb08c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/897cb08c
Branch: refs/heads/master
Commit: 897cb08c54341fd8c3021f0c366197494f39c718
Parents: 1968a52
Author: duc <dt...@linagora.com>
Authored: Thu Aug 23 23:09:09 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:00 2018 +0200
----------------------------------------------------------------------
javax-mail-extension/pom.xml | 4 +
.../org/apache/james/javax/AddressHelper.java | 37 +
pom.xml | 5 +
.../transport/matchers/dlp/DlpDomainRules.java | 17 +-
server/protocols/jmap/pom.xml | 30 +-
.../james/jmap/mailet/filter/ActionApplier.java | 101 +++
.../james/jmap/mailet/filter/JMAPFiltering.java | 85 +++
.../james/jmap/mailet/filter/MailMatcher.java | 225 ++++++
.../james/jmap/mailet/filter/RuleMatcher.java | 44 ++
.../mailet/filter/JMAPFilteringExtension.java | 151 ++++
.../mailet/filter/JMAPFilteringFixture.java | 59 ++
.../jmap/mailet/filter/JMAPFilteringTest.java | 731 +++++++++++++++++++
12 files changed, 1471 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/javax-mail-extension/pom.xml
----------------------------------------------------------------------
diff --git a/javax-mail-extension/pom.xml b/javax-mail-extension/pom.xml
index 2e2fa74..d23866d 100644
--- a/javax-mail-extension/pom.xml
+++ b/javax-mail-extension/pom.xml
@@ -40,5 +40,9 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>apache-mime4j-core</artifactId>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/javax-mail-extension/src/main/java/org/apache/james/javax/AddressHelper.java
----------------------------------------------------------------------
diff --git a/javax-mail-extension/src/main/java/org/apache/james/javax/AddressHelper.java b/javax-mail-extension/src/main/java/org/apache/james/javax/AddressHelper.java
new file mode 100644
index 0000000..fb0084c
--- /dev/null
+++ b/javax-mail-extension/src/main/java/org/apache/james/javax/AddressHelper.java
@@ -0,0 +1,37 @@
+/****************************************************************
+ * 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.javax;
+
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+import javax.mail.Address;
+
+import org.apache.james.mime4j.util.MimeUtil;
+
+public class AddressHelper {
+ public static Stream<String> asStringStream(Address[] addresses) {
+ return Arrays.stream(addresses).map(AddressHelper::asString);
+ }
+
+ private static String asString(Address address) {
+ return MimeUtil.unscrambleHeaderValue(address.toString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 4368273..9c9028a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2401,6 +2401,11 @@
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-engine</artifactId>
+ <version>${junit.plateform.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>${junit.plateform.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
index f44a60e..d3f0eef 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
@@ -19,14 +19,14 @@
package org.apache.james.transport.matchers.dlp;
+import static org.apache.james.javax.AddressHelper.asStringStream;
+
import java.io.IOException;
-import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Stream;
-import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
@@ -36,8 +36,8 @@ import javax.mail.internet.MimeMessage;
import org.apache.james.core.MailAddress;
import org.apache.james.dlp.api.DLPConfigurationItem;
import org.apache.james.dlp.api.DLPConfigurationItem.Targets;
+import org.apache.james.javax.AddressHelper;
import org.apache.james.javax.MultipartUtil;
-import org.apache.james.mime4j.util.MimeUtil;
import org.apache.james.util.OptionalUtils;
import org.apache.mailet.Mail;
@@ -71,15 +71,6 @@ public class DlpDomainRules {
interface MatcherFunction extends ThrowingPredicate<Mail> { }
-
- private static Stream<String> asStringStream(Address[] addresses) {
- return Arrays.stream(addresses).map(Rule::asString);
- }
-
- private static String asString(Address address) {
- return MimeUtil.unscrambleHeaderValue(address.toString());
- }
-
private static class ContentMatcher implements Rule.MatcherFunction {
private final Pattern pattern;
@@ -153,7 +144,7 @@ public class DlpDomainRules {
private Stream<String> listHeaderRecipients(Mail mail) throws MessagingException {
return Optional.ofNullable(mail.getMessage())
.flatMap(Throwing.function(m -> Optional.ofNullable(m.getAllRecipients())))
- .map(Rule::asStringStream)
+ .map(AddressHelper::asStringStream)
.orElse(Stream.of());
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/server/protocols/jmap/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/pom.xml b/server/protocols/jmap/pom.xml
index 8818166..93495fb 100644
--- a/server/protocols/jmap/pom.xml
+++ b/server/protocols/jmap/pom.xml
@@ -78,6 +78,11 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-memory</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
<artifactId>james-mdn</artifactId>
</dependency>
<dependency>
@@ -212,11 +217,6 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>net.javacrumbs.json-unit</groupId>
<artifactId>json-unit-assertj</artifactId>
<scope>test</scope>
@@ -264,6 +264,26 @@
<version>1.2</version>
</dependency>
<dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.vintage</groupId>
+ <artifactId>junit-vintage-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
<version>1.2.0</version>
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
new file mode 100644
index 0000000..fdb55ac
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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.jmap.mailet.filter;
+
+import javax.inject.Inject;
+
+import org.apache.james.core.User;
+import org.apache.james.jmap.api.filtering.Rule;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.mailet.Mail;
+
+import com.github.fge.lambdas.Throwing;
+import com.google.common.annotations.VisibleForTesting;
+
+public class ActionApplier {
+ static final String DELIVERY_PATH_PREFIX = "DeliveryPath_";
+
+ @VisibleForTesting
+ static class Factory {
+ private final MailboxManager mailboxManager;
+ private final MailboxId.Factory mailboxIdFactory;
+
+ @Inject
+ Factory(MailboxManager mailboxManager, MailboxId.Factory mailboxIdFactory) {
+ this.mailboxManager = mailboxManager;
+ this.mailboxIdFactory = mailboxIdFactory;
+ }
+
+ public RequireUser forMail(Mail mail) {
+ return new RequireUser(mail);
+ }
+
+ public class RequireUser {
+ private final Mail mail;
+
+ RequireUser(Mail mail) {
+ this.mail = mail;
+ }
+
+ public ActionApplier forUser(User user) {
+ return new ActionApplier(mailboxManager, mailboxIdFactory, mail, user);
+ }
+ }
+ }
+
+ private final MailboxManager mailboxManager;
+ private final MailboxId.Factory mailboxIdFactory;
+ private final Mail mail;
+ private final User user;
+
+ @VisibleForTesting
+ public static Factory factory(MailboxManager mailboxManager, MailboxId.Factory mailboxIdFactory) {
+ return new Factory(mailboxManager, mailboxIdFactory);
+ }
+
+ private ActionApplier(MailboxManager mailboxManager, MailboxId.Factory mailboxIdFactory, Mail mail, User user) {
+ this.mailboxManager = mailboxManager;
+ this.mailboxIdFactory = mailboxIdFactory;
+ this.mail = mail;
+ this.user = user;
+ }
+
+ public void apply(Rule.Action action) {
+ action.getAppendInMailboxes()
+ .getMailboxIds()
+ .stream()
+ .findFirst()
+ .map(mailboxIdFactory::fromString)
+ .ifPresent(Throwing.consumer(this::addStorageDirective));
+ }
+
+ private void addStorageDirective(MailboxId mailboxId) throws MailboxException {
+ MailboxSession mailboxSession = mailboxManager.createSystemSession(user.asString());
+ MessageManager messageManager = mailboxManager.getMailbox(mailboxId, mailboxSession);
+
+ String mailboxName = messageManager.getMailboxPath().getName();
+ String attributeNameForUser = DELIVERY_PATH_PREFIX + user.asString();
+ mail.setAttribute(attributeNameForUser, mailboxName);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
new file mode 100644
index 0000000..388fabe
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
@@ -0,0 +1,85 @@
+/****************************************************************
+ * 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.jmap.mailet.filter;
+
+import java.util.List;
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.core.User;
+import org.apache.james.jmap.api.filtering.FilteringManagement;
+import org.apache.james.jmap.api.filtering.Rule;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.GenericMailet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JMAPFiltering extends GenericMailet {
+
+ private final Logger logger = LoggerFactory.getLogger(JMAPFiltering.class);
+
+ private final FilteringManagement filteringManagement;
+ private final UsersRepository usersRepository;
+ private final ActionApplier.Factory actionApplierFactory;
+
+ @Inject
+ public JMAPFiltering(FilteringManagement filteringManagement,
+ UsersRepository usersRepository, ActionApplier.Factory actionApplierFactory) {
+
+ this.filteringManagement = filteringManagement;
+ this.usersRepository = usersRepository;
+ this.actionApplierFactory = actionApplierFactory;
+ }
+
+ @Override
+ public void service(Mail mail) {
+ mail.getRecipients()
+ .forEach(recipient -> filteringForRecipient(mail, recipient));
+ }
+
+ private void filteringForRecipient(Mail mail, MailAddress recipient) {
+ Optional<User> maybeUser = retrieveUser(recipient);
+ maybeUser
+ .ifPresent(user -> findFirstApplicableRule(user, mail));
+ }
+
+ private void findFirstApplicableRule(User user, Mail mail) {
+ List<Rule> filteringRules = filteringManagement.listRulesForUser(user);
+ RuleMatcher ruleMatcher = new RuleMatcher(filteringRules);
+ Optional<Rule> maybeMatchingRule = ruleMatcher.findApplicableRule(mail);
+
+ maybeMatchingRule.ifPresent(rule -> actionApplierFactory.forMail(mail)
+ .forUser(user)
+ .apply(rule.getAction()));
+ }
+
+ private Optional<User> retrieveUser(MailAddress recipient) {
+ try {
+ return Optional.ofNullable(User.fromUsername(usersRepository.getUser(recipient)));
+ } catch (UsersRepositoryException e) {
+ logger.error("cannot retrieve user " + recipient.asString(), e);
+ return Optional.empty();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
new file mode 100644
index 0000000..c9ea72b
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -0,0 +1,225 @@
+/****************************************************************
+ * 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.jmap.mailet.filter;
+
+import static org.apache.james.jmap.api.filtering.Rule.Condition;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import javax.mail.Address;
+import javax.mail.Message;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.james.javax.AddressHelper;
+import org.apache.james.jmap.api.filtering.Rule;
+import org.apache.james.jmap.api.filtering.Rule.Condition.Field;
+import org.apache.mailet.Mail;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.fge.lambdas.functions.ThrowingFunction;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
+public interface MailMatcher {
+
+ interface HeaderExtractor extends ThrowingFunction<Mail, Stream<String>> {}
+
+ class HeaderMatcher implements MailMatcher {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HeaderMatcher.class);
+
+ private final ContentMatcher contentMatcher;
+ private final String ruleValue;
+ private final HeaderExtractor headerExtractor;
+
+ private HeaderMatcher(ContentMatcher contentMatcher, String ruleValue,
+ HeaderExtractor headerExtractor) {
+ Preconditions.checkNotNull(contentMatcher);
+ Preconditions.checkNotNull(headerExtractor);
+
+ this.contentMatcher = contentMatcher;
+ this.ruleValue = ruleValue;
+ this.headerExtractor = headerExtractor;
+ }
+
+ @Override
+ public boolean match(Mail mail) {
+ try {
+ final Stream<String> headerLines = headerExtractor.apply(mail);
+ return contentMatcher.match(headerLines, ruleValue);
+ } catch (Exception e) {
+ LOGGER.error("error while extracting mail header", e);
+ return false;
+ }
+ }
+ }
+
+ interface ContentMatcher {
+
+ class AddressHeader {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AddressHeader.class);
+
+ private final Optional<String> personal;
+ private final Optional<String> address;
+ private final String fullAddress;
+
+ private AddressHeader(String fullAddress) {
+ this.fullAddress = fullAddress;
+ Optional<InternetAddress> internetAddress = parseFullAddress();
+ this.personal = internetAddress.map(InternetAddress::getPersonal);
+ this.address = internetAddress.map(InternetAddress::getAddress);
+ }
+
+ private Optional<InternetAddress> parseFullAddress() {
+ try {
+ return Optional.of(new InternetAddress(fullAddress));
+ } catch (AddressException e) {
+ LOGGER.error("error while parsing full address {}", fullAddress, e);
+ return Optional.empty();
+ }
+ }
+
+ public Optional<String> getPersonal() {
+ return personal;
+ }
+
+ public Optional<String> getAddress() {
+ return address;
+ }
+
+ public String getFullAddress() {
+ return fullAddress;
+ }
+ }
+
+ ContentMatcher STRING_CONTAINS_MATCHER = (contents, valueToMatch) -> contents.anyMatch(content -> StringUtils.contains(content, valueToMatch));
+ ContentMatcher STRING_NOT_CONTAINS_MATCHER = negate(STRING_CONTAINS_MATCHER);
+ ContentMatcher STRING_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents.anyMatch(content -> StringUtils.equals(content, valueToMatch));
+ ContentMatcher STRING_NOT_EXACTLY_EQUALS_MATCHER = negate(STRING_EXACTLY_EQUALS_MATCHER);
+
+ Map<Rule.Condition.Comparator, ContentMatcher> CONTENT_STRING_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
+ .put(Condition.Comparator.CONTAINS, STRING_CONTAINS_MATCHER)
+ .put(Condition.Comparator.NOT_CONTAINS, STRING_NOT_CONTAINS_MATCHER)
+ .put(Condition.Comparator.EXACTLY_EQUALS, STRING_EXACTLY_EQUALS_MATCHER)
+ .put(Condition.Comparator.NOT_EXACTLY_EQUALS, STRING_NOT_EXACTLY_EQUALS_MATCHER)
+ .build();
+
+ ContentMatcher ADDRESS_CONTAINS_MATCHER = (contents, valueToMatch) -> contents
+ .map(ContentMatcher::asAddressHeader)
+ .anyMatch(addressHeader -> StringUtils.containsIgnoreCase(addressHeader.getFullAddress(), valueToMatch));
+
+ ContentMatcher ADDRESS_NOT_CONTAINS_MATCHER = negate(ADDRESS_CONTAINS_MATCHER);
+ ContentMatcher ADDRESS_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents
+ .map(ContentMatcher::asAddressHeader)
+ .anyMatch(addressHeader ->
+ StringUtils.equalsIgnoreCase(addressHeader.getFullAddress(), valueToMatch)
+ || StringUtils.equalsIgnoreCase(addressHeader.getAddress().orElse(null), valueToMatch)
+ || StringUtils.equalsIgnoreCase(addressHeader.getPersonal().orElse(null), valueToMatch));
+
+ ContentMatcher ADDRESS_NOT_EXACTLY_EQUALS_MATCHER = negate(ADDRESS_EXACTLY_EQUALS_MATCHER);
+
+ Map<Rule.Condition.Comparator, ContentMatcher> HEADER_ADDRESS_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
+ .put(Condition.Comparator.CONTAINS, ADDRESS_CONTAINS_MATCHER)
+ .put(Condition.Comparator.NOT_CONTAINS, ADDRESS_NOT_CONTAINS_MATCHER)
+ .put(Condition.Comparator.EXACTLY_EQUALS, ADDRESS_EXACTLY_EQUALS_MATCHER)
+ .put(Condition.Comparator.NOT_EXACTLY_EQUALS, ADDRESS_NOT_EXACTLY_EQUALS_MATCHER)
+ .build();
+
+ Map<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>> CONTENT_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>>builder()
+ .put(Condition.Field.SUBJECT, CONTENT_STRING_MATCHER_REGISTRY)
+ .put(Condition.Field.TO, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .put(Condition.Field.CC, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .put(Condition.Field.RECIPIENT, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .put(Condition.Field.FROM, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .build();
+
+ static ContentMatcher negate(ContentMatcher contentMatcher) {
+ return (Stream<String> contents, String valueToMatch) ->
+ !contentMatcher.match(contents, valueToMatch);
+ }
+
+ static Optional<ContentMatcher> asContentMatcher(Condition.Field field, Condition.Comparator comparator) {
+ return Optional
+ .ofNullable(CONTENT_MATCHER_REGISTRY.get(field))
+ .map(matcherRegistry -> matcherRegistry.get(comparator));
+ }
+
+ static AddressHeader asAddressHeader(String addressAsString) {
+ return new AddressHeader(addressAsString);
+ }
+
+ boolean match(Stream<String> contents, String valueToMatch);
+ }
+
+ HeaderExtractor SUBJECT_EXTRACTOR = mail ->
+ Optional.ofNullable(mail.getMessage().getSubject())
+ .map(Stream::of)
+ .orElse(Stream.empty());
+ HeaderExtractor RECIPIENT_EXTRACTOR = mail -> addressExtractor(
+ ArrayUtils.addAll(
+ mail.getMessage().getRecipients(Message.RecipientType.TO),
+ mail.getMessage().getRecipients(Message.RecipientType.CC)));
+
+ HeaderExtractor FROM_EXTRACTOR = mail -> addressExtractor(mail.getMessage().getFrom());
+ HeaderExtractor CC_EXTRACTOR = recipientExtractor(Message.RecipientType.CC);
+ HeaderExtractor TO_EXTRACTOR = recipientExtractor(Message.RecipientType.TO);
+
+ Map<Field, HeaderExtractor> HEADER_EXTRACTOR_REGISTRY = ImmutableMap.<Field, HeaderExtractor>builder()
+ .put(Field.SUBJECT, SUBJECT_EXTRACTOR)
+ .put(Field.RECIPIENT, RECIPIENT_EXTRACTOR)
+ .put(Field.FROM, FROM_EXTRACTOR)
+ .put(Field.CC, CC_EXTRACTOR)
+ .put(Field.TO, TO_EXTRACTOR)
+ .build();
+
+ static MailMatcher from(Rule rule) {
+ Condition ruleCondition = rule.getCondition();
+ Optional<ContentMatcher> maybeContentMatcher = ContentMatcher.asContentMatcher(ruleCondition.getField(), ruleCondition.getComparator());
+ Optional<HeaderExtractor> maybeHeaderExtractor = getHeaderExtractor(ruleCondition.getField());
+
+ return new HeaderMatcher(
+ maybeContentMatcher.orElseThrow(() -> new RuntimeException("No content matcher associated with field " + ruleCondition.getField())),
+ rule.getCondition().getValue(),
+ maybeHeaderExtractor.orElseThrow(() -> new RuntimeException("No content matcher associated with comparator " + ruleCondition.getComparator())));
+ }
+
+ static HeaderExtractor recipientExtractor(Message.RecipientType type) {
+ return mail -> addressExtractor(mail.getMessage().getRecipients(type));
+ }
+
+ static Stream<String> addressExtractor(Address[] addresses) {
+ return Optional.ofNullable(addresses)
+ .map(AddressHelper::asStringStream)
+ .orElse(Stream.empty());
+ }
+
+ static Optional<HeaderExtractor> getHeaderExtractor(Field field) {
+ return Optional
+ .ofNullable(HEADER_EXTRACTOR_REGISTRY.get(field));
+ }
+
+ boolean match(Mail mail);
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/RuleMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/RuleMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/RuleMatcher.java
new file mode 100644
index 0000000..abc1da1
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/RuleMatcher.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.jmap.mailet.filter;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.james.jmap.api.filtering.Rule;
+import org.apache.mailet.Mail;
+
+import com.google.common.base.Preconditions;
+
+class RuleMatcher {
+ private final List<Rule> filteringRules;
+
+ RuleMatcher(List<Rule> filteringRules) {
+ Preconditions.checkNotNull(filteringRules);
+
+ this.filteringRules = filteringRules;
+ }
+
+ Optional<Rule> findApplicableRule(Mail mail) {
+ return filteringRules.stream()
+ .filter(rule -> MailMatcher.from(rule).match(mail))
+ .findFirst();
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringExtension.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringExtension.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringExtension.java
new file mode 100644
index 0000000..05dc317
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringExtension.java
@@ -0,0 +1,151 @@
+/****************************************************************
+ * 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.jmap.mailet.filter;
+
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1_MAILBOX_1;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1_USERNAME;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_1_ADDRESS;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.mail.MessagingException;
+
+import org.apache.james.core.User;
+import org.apache.james.core.builder.MimeMessageBuilder;
+import org.apache.james.eventsourcing.eventstore.memory.InMemoryEventStore;
+import org.apache.james.jmap.api.filtering.FilteringManagement;
+import org.apache.james.jmap.api.filtering.Rule;
+import org.apache.james.jmap.api.filtering.impl.EventSourcingFilteringManagement;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.inmemory.InMemoryId;
+import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
+import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.user.memory.MemoryUsersRepository;
+import org.apache.mailet.base.test.FakeMail;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+import com.google.common.collect.ImmutableList;
+
+public class JMAPFilteringExtension implements BeforeEachCallback, ParameterResolver {
+
+ class JMAPFilteringTestSystem {
+
+ private final JMAPFiltering jmapFiltering;
+ private final FilteringManagement filteringManagement;
+ private final InMemoryMailboxManager mailboxManager;
+ private final MailboxId recipient1Mailbox;
+
+ JMAPFilteringTestSystem(JMAPFiltering jmapFiltering, FilteringManagement filteringManagement,
+ InMemoryMailboxManager mailboxManager) {
+ this.jmapFiltering = jmapFiltering;
+ this.filteringManagement = filteringManagement;
+ this.mailboxManager = mailboxManager;
+ try {
+ this.recipient1Mailbox = createMailbox(mailboxManager, RECIPIENT_1_USERNAME, RECIPIENT_1_MAILBOX_1);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public JMAPFiltering getJmapFiltering() {
+ return jmapFiltering;
+ }
+
+ public FilteringManagement getFilteringManagement() {
+ return filteringManagement;
+ }
+
+ public InMemoryMailboxManager getMailboxManager() {
+ return mailboxManager;
+ }
+
+ public MailboxId getRecipient1MailboxId() {
+ return recipient1Mailbox;
+ }
+
+ public MailboxId createMailbox(InMemoryMailboxManager mailboxManager, String username, String mailboxName) throws Exception {
+ MailboxSession mailboxSession = mailboxManager.createSystemSession(username);
+ return mailboxManager
+ .createMailbox(MailboxPath.forUser(username, mailboxName), mailboxSession)
+ .orElseThrow(() -> new RuntimeException("Missing mailboxId when creating mailbox"));
+ }
+
+ public void defineRulesForRecipient1(Rule.Condition... conditions) {
+ defineRulesForRecipient1(Arrays.asList(conditions));
+ }
+
+ public void defineRulesForRecipient1(List<Rule.Condition> conditions) {
+ AtomicInteger counter = new AtomicInteger();
+ ImmutableList<Rule> rules = conditions
+ .stream()
+ .map(condition -> Rule.builder()
+ .id(Rule.Id.of(String.valueOf(counter.incrementAndGet())))
+ .name(String.valueOf(counter.incrementAndGet()))
+ .condition(condition)
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(testSystem.getRecipient1MailboxId().serialize())))
+ .build())
+ .collect(ImmutableList.toImmutableList());
+
+ testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME), rules);
+ }
+
+ public FakeMail asMail(MimeMessageBuilder mimeMessageBuilder) throws MessagingException {
+ return FakeMail.builder()
+ .sender(USER_1_ADDRESS)
+ .recipients(RECIPIENT_1)
+ .mimeMessage(mimeMessageBuilder)
+ .build();
+ }
+ }
+
+ private JMAPFilteringTestSystem testSystem;
+
+ @Override
+ public void beforeEach(ExtensionContext extensionContext) throws Exception {
+ FilteringManagement filteringManagement = new EventSourcingFilteringManagement(new InMemoryEventStore());
+ MemoryUsersRepository usersRepository = MemoryUsersRepository.withoutVirtualHosting();
+ InMemoryMailboxManager mailboxManager = new InMemoryIntegrationResources().createMailboxManager(new SimpleGroupMembershipResolver());
+ ActionApplier.Factory actionApplierFactory = ActionApplier.factory(mailboxManager, new InMemoryId.Factory());
+
+ JMAPFiltering jmapFiltering = new JMAPFiltering(filteringManagement, usersRepository, actionApplierFactory);
+
+ testSystem = new JMAPFilteringTestSystem(jmapFiltering, filteringManagement, mailboxManager);
+ }
+
+ @Override
+ public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+ return (parameterContext.getParameter().getType() == JMAPFilteringTestSystem.class);
+ }
+
+ @Override
+ public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+ return testSystem;
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringFixture.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringFixture.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringFixture.java
new file mode 100644
index 0000000..1b4792b
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringFixture.java
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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.jmap.mailet.filter;
+
+public interface JMAPFilteringFixture {
+ String GA_BOU_ZO_MEU_FULL_ADDRESS = "GA BOU ZO MEU <GA...@james.org>";
+ String BOU = "BOU";
+
+ String USER_1_FULL_ADDRESS = "user1 <us...@james.org>";
+ String USER_1_ADDRESS = "user1@james.org";
+ String USER_1_USERNAME = "user1";
+
+ String USER_2_FULL_ADDRESS = "user2 <us...@james.org>";
+ String USER_2_ADDRESS = "user2@james.org";
+ String USER_2_USERNAME = "user2";
+
+ String USER_1_AND_UNFOLDED_USER_FULL_ADDRESS = "user2 <se...@james.org>, \r\nunfolded\r\n_user\r\n <un...@james.org>";
+
+ String USER_3_FULL_ADDRESS = "user3 <us...@james.org>";
+ String USER_3_ADDRESS = "user3@james.org";
+ String USER_3_USERNAME = "user3";
+
+ String USER_4_FULL_ADDRESS = "user4 <us...@james.org>";
+
+ String SCRAMBLED_SUBJECT = "this is the subject =?UTF-8?B?RnLDqWTDqXJpYyBNQVJUSU4=?= of the mail";
+ String UNSCRAMBLED_SUBJECT = "this is the subject Frédéric MARTIN of the mail";
+ String SHOULD_NOT_MATCH = "should not match";
+
+ String RECIPIENT_1 = "recipient1@james.org";
+ String RECIPIENT_1_USERNAME = "recipient1";
+ String RECIPIENT_1_MAILBOX_1 = "recipient1_maibox1";
+
+ String FRED_MARTIN_FULLNAME = "Frédéric MARTIN";
+ String FRED_MARTIN_FULL_SCRAMBLED_ADDRESS = "=?UTF-8?B?RnLDqWTDqXJpYyBNQVJUSU4=?= <fr...@linagora.com>";
+
+ String UNFOLDED_USERNAME = "unfolded_user";
+
+ String EMPTY = "";
+
+ String TO_HEADER = "to";
+ String CC_HEADER = "cc";
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/897cb08c/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
new file mode 100644
index 0000000..0d697f8
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
@@ -0,0 +1,731 @@
+/****************************************************************
+ * 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.jmap.mailet.filter;
+
+import static org.apache.james.core.builder.MimeMessageBuilder.mimeMessageBuilder;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.CONTAINS;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.EXACTLY_EQUALS;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.NOT_CONTAINS;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.NOT_EXACTLY_EQUALS;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.CC;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.FROM;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.RECIPIENT;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.SUBJECT;
+import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.TO;
+import static org.apache.james.jmap.mailet.filter.ActionApplier.DELIVERY_PATH_PREFIX;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.BOU;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.CC_HEADER;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.EMPTY;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.FRED_MARTIN_FULLNAME;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.FRED_MARTIN_FULL_SCRAMBLED_ADDRESS;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.GA_BOU_ZO_MEU_FULL_ADDRESS;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1_MAILBOX_1;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1_USERNAME;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.SCRAMBLED_SUBJECT;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.SHOULD_NOT_MATCH;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.TO_HEADER;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.UNFOLDED_USERNAME;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.UNSCRAMBLED_SUBJECT;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_1_ADDRESS;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_1_AND_UNFOLDED_USER_FULL_ADDRESS;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_1_FULL_ADDRESS;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_1_USERNAME;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_2_ADDRESS;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_2_FULL_ADDRESS;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_3_ADDRESS;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_3_FULL_ADDRESS;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_3_USERNAME;
+import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_4_FULL_ADDRESS;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Locale;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.apache.james.core.User;
+import org.apache.james.core.builder.MimeMessageBuilder;
+import org.apache.james.jmap.api.filtering.Rule;
+import org.apache.james.jmap.mailet.filter.JMAPFilteringExtension.JMAPFilteringTestSystem;
+import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.util.StreamUtils;
+import org.apache.mailet.base.test.FakeMail;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+@ExtendWith(JMAPFilteringExtension.class)
+class JMAPFilteringTest {
+
+ static class FilteringArgumentBuilder {
+ private Optional<String> description;
+ private Optional<Rule.Condition.Field> field;
+ private MimeMessageBuilder mimeMessageBuilder;
+ private Optional<String> valueToMatch;
+
+ private FilteringArgumentBuilder() {
+ this.description = Optional.empty();
+ this.field = Optional.empty();
+ mimeMessageBuilder = MimeMessageBuilder.mimeMessageBuilder();
+ this.valueToMatch = Optional.empty();
+ }
+
+ public FilteringArgumentBuilder description(String description) {
+ this.description = Optional.ofNullable(description);
+ return this;
+ }
+
+ public FilteringArgumentBuilder field(Rule.Condition.Field field) {
+ this.field = Optional.ofNullable(field);
+ return this;
+ }
+
+ public FilteringArgumentBuilder from(String from) {
+ Optional.ofNullable(from).ifPresent(Throwing.consumer(mimeMessageBuilder::addFrom));
+ return this;
+ }
+
+ public FilteringArgumentBuilder noHeader() {
+ return this;
+ }
+
+ public FilteringArgumentBuilder toRecipient(String toRecipient) {
+ Optional.ofNullable(toRecipient).ifPresent(Throwing.consumer(mimeMessageBuilder::addToRecipient));
+ return this;
+ }
+
+ public FilteringArgumentBuilder ccRecipient(String ccRecipient) {
+ Optional.ofNullable(ccRecipient).ifPresent(Throwing.consumer(mimeMessageBuilder::addCcRecipient));
+ return this;
+ }
+
+ public FilteringArgumentBuilder bccRecipient(String bccRecipient) {
+ Optional.ofNullable(bccRecipient).ifPresent(Throwing.consumer(mimeMessageBuilder::addBccRecipient));
+ return this;
+ }
+
+ public FilteringArgumentBuilder header(String headerName, String headerValue) {
+ mimeMessageBuilder.addHeader(headerName, headerValue);
+ return this;
+ }
+
+ public FilteringArgumentBuilder headerForField(String headerValue) {
+ Preconditions.checkState(field.isPresent(), "field should be set first");
+
+ mimeMessageBuilder.addHeader(field.get().asString(), headerValue);
+ return this;
+ }
+
+ public FilteringArgumentBuilder subject(String subject) {
+ mimeMessageBuilder.setSubject(subject);
+ return this;
+ }
+
+ public FilteringArgumentBuilder valueToMatch(String valueToMatch) {
+ this.valueToMatch = Optional.ofNullable(valueToMatch);
+ return this;
+ }
+
+ public FilteringArgumentBuilder scrambledSubjectToMatch(String valueToMatch) {
+ return description("normal content")
+ .field(SUBJECT)
+ .subject(SCRAMBLED_SUBJECT)
+ .valueToMatch(valueToMatch);
+ }
+
+ public FilteringArgumentBuilder scrambledSubjectShouldNotMatchCaseSensitive() {
+ return description("normal content (case sensitive)")
+ .field(SUBJECT)
+ .subject(SCRAMBLED_SUBJECT)
+ .valueToMatch(SCRAMBLED_SUBJECT.toUpperCase(Locale.FRENCH));
+ }
+
+ public FilteringArgumentBuilder unscrambledSubjectToMatch(String valueToMatch) {
+ return description("unscrambled content")
+ .field(SUBJECT)
+ .subject(UNSCRAMBLED_SUBJECT)
+ .valueToMatch(valueToMatch);
+ }
+
+ public FilteringArgumentBuilder unscrambledSubjectShouldNotMatchCaseSensitive() {
+ return description("unscrambled content (case sensitive)")
+ .field(SUBJECT)
+ .subject(UNSCRAMBLED_SUBJECT)
+ .valueToMatch(UNSCRAMBLED_SUBJECT.toUpperCase(Locale.FRENCH));
+ }
+
+ public Arguments build() {
+ Preconditions.checkState(description.isPresent());
+ Preconditions.checkState(field.isPresent());
+ Preconditions.checkState(valueToMatch.isPresent());
+
+ return Arguments.of(description.get(), field.get(), mimeMessageBuilder, valueToMatch.get());
+ }
+
+ }
+
+ static FilteringArgumentBuilder argumentBuilder() {
+ return new FilteringArgumentBuilder();
+ }
+
+ static FilteringArgumentBuilder argumentBuilder(Rule.Condition.Field field) {
+ return new FilteringArgumentBuilder()
+ .field(field);
+ }
+
+ static Stream<Arguments> exactlyEqualsTestSuite() {
+ return StreamUtils.flatten(
+ Stream.of(FROM, TO, CC)
+ .flatMap(headerField -> Stream.of(
+ argumentBuilder(headerField)
+ .description("full address value")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch(USER_1_USERNAME),
+ argumentBuilder(headerField)
+ .description("full address value (different case)")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch(USER_1_USERNAME.toUpperCase(Locale.ENGLISH)),
+ argumentBuilder(headerField)
+ .description("address only value")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch(USER_1_ADDRESS),
+ argumentBuilder(headerField)
+ .description("address only value (different case)")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch(USER_1_ADDRESS.toUpperCase(Locale.ENGLISH)),
+ argumentBuilder(headerField)
+ .description("personal only value")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch(USER_1_FULL_ADDRESS),
+ argumentBuilder(headerField)
+ .description("personal only value (different case)")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch(USER_1_FULL_ADDRESS.toUpperCase()),
+ argumentBuilder(headerField)
+ .description("personal header should match personal")
+ .headerForField(USER_1_USERNAME)
+ .valueToMatch(USER_1_USERNAME),
+ argumentBuilder(headerField)
+ .description("address header should match address")
+ .headerForField(USER_1_ADDRESS)
+ .valueToMatch(USER_1_ADDRESS),
+ argumentBuilder(headerField)
+ .description("multiple headers")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .headerForField(USER_2_FULL_ADDRESS)
+ .valueToMatch(USER_1_USERNAME),
+ argumentBuilder(headerField)
+ .description("scrambled content")
+ .headerForField(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
+ .valueToMatch(FRED_MARTIN_FULLNAME),
+ argumentBuilder(headerField)
+ .description("folded content")
+ .headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .valueToMatch(UNFOLDED_USERNAME),
+ argumentBuilder(headerField)
+ .description("folded content (different case)")
+ .headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .valueToMatch(UNFOLDED_USERNAME.toUpperCase())
+ ).map(FilteringArgumentBuilder::build)),
+ Stream.of(TO_HEADER, CC_HEADER)
+ .flatMap(headerName -> Stream.of(
+ argumentBuilder()
+ .description("full address " + headerName + " header")
+ .field(RECIPIENT)
+ .header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch(USER_3_FULL_ADDRESS)
+ .build(),
+ argumentBuilder()
+ .description("full address " + headerName + " header (different case)")
+ .field(RECIPIENT)
+ .header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch(USER_3_FULL_ADDRESS.toUpperCase(Locale.ENGLISH))
+ .build(),
+ argumentBuilder()
+ .description("address only " + headerName + " header")
+ .field(RECIPIENT).header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch(USER_3_ADDRESS)
+ .build(),
+ argumentBuilder()
+ .description("personal only " + headerName + " header")
+ .field(RECIPIENT)
+ .header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch(USER_3_USERNAME)
+ .build(),
+ argumentBuilder()
+ .description("scrambled content in " + headerName + " header")
+ .field(RECIPIENT)
+ .header(headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
+ .valueToMatch(FRED_MARTIN_FULLNAME)
+ .build(),
+ argumentBuilder()
+ .description("folded content in " + headerName + " header")
+ .field(RECIPIENT)
+ .header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .valueToMatch(UNFOLDED_USERNAME)
+ .build())),
+ Stream.of(
+ argumentBuilder().description("multiple to and cc headers").field(RECIPIENT)
+ .ccRecipient(USER_1_FULL_ADDRESS)
+ .ccRecipient(USER_2_FULL_ADDRESS)
+ .toRecipient(USER_3_FULL_ADDRESS)
+ .toRecipient(USER_4_FULL_ADDRESS)
+ .valueToMatch(USER_4_FULL_ADDRESS)
+ .build(),
+ argumentBuilder().scrambledSubjectToMatch(UNSCRAMBLED_SUBJECT).build(),
+ argumentBuilder().unscrambledSubjectToMatch(UNSCRAMBLED_SUBJECT).build()));
+ }
+
+ static Stream<Arguments> containsTestSuite() {
+ return Stream.concat(
+ exactlyEqualsTestSuite(),
+ containsArguments());
+ }
+
+ private static Stream<Arguments> containsArguments() {
+ return StreamUtils.flatten(
+ Stream.of(FROM, TO, CC)
+ .flatMap(headerField -> Stream.of(
+ argumentBuilder(headerField)
+ .description("full address value (partial matching)")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch("ser1 <"),
+ argumentBuilder(headerField)
+ .description("full address value (partial matching, different case)")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch("SER1 <"),
+ argumentBuilder(headerField)
+ .description("address only value (partial matching)")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch("ser1@jam"),
+ argumentBuilder(headerField)
+ .description("personal only value (partial matching)")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch("ser1"),
+ argumentBuilder(headerField)
+ .description("address header & match in the address (partial matching)")
+ .headerForField(USER_1_ADDRESS)
+ .valueToMatch("ser1@jam"),
+ argumentBuilder(headerField)
+ .description("raw value matching (partial matching)")
+ .headerForField(GA_BOU_ZO_MEU_FULL_ADDRESS)
+ .valueToMatch(BOU),
+ argumentBuilder(headerField)
+ .description("multiple headers (partial matching)")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .headerForField(USER_2_FULL_ADDRESS)
+ .valueToMatch("ser1@jam"),
+ argumentBuilder(headerField)
+ .description("scrambled content (partial matching)")
+ .headerForField(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
+ .valueToMatch("déric MAR"),
+ argumentBuilder(headerField)
+ .description("folded content (partial matching)")
+ .headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .valueToMatch("ded_us"))
+ .map(FilteringArgumentBuilder::build)),
+ Stream.of(TO_HEADER, CC_HEADER)
+ .flatMap(headerName -> Stream.of(
+ argumentBuilder()
+ .description("full address " + headerName + " header (partial matching)")
+ .field(RECIPIENT)
+ .header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch("ser3 <us")
+ .build(),
+ argumentBuilder()
+ .description("full address " + headerName + " header (partial matching, different case)")
+ .field(RECIPIENT)
+ .header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch("SER3 <US")
+ .build(),
+ argumentBuilder()
+ .description("address only " + headerName + " header (partial matching)")
+ .field(RECIPIENT)
+ .header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch("ser3@jam")
+ .build(),
+ argumentBuilder()
+ .description("personal only " + headerName + " header (partial matching)")
+ .field(RECIPIENT)
+ .header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch("ser3")
+ .build(),
+ argumentBuilder()
+ .description("scrambled content in " + headerName + " header (partial matching)")
+ .field(RECIPIENT)
+ .header(headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
+ .valueToMatch("déric MAR")
+ .build(),
+ argumentBuilder()
+ .description("folded content in " + headerName + " header (partial matching)")
+ .field(RECIPIENT)
+ .header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .valueToMatch("folded_us")
+ .build())),
+ Stream.of(
+ argumentBuilder().description("multiple to and cc headers (partial matching)").field(RECIPIENT)
+ .ccRecipient(USER_1_FULL_ADDRESS)
+ .ccRecipient(USER_2_FULL_ADDRESS)
+ .toRecipient(USER_3_FULL_ADDRESS)
+ .toRecipient(USER_4_FULL_ADDRESS)
+ .valueToMatch("user4@jam").build(),
+ argumentBuilder().scrambledSubjectToMatch("is the subject").build(),
+ argumentBuilder().unscrambledSubjectToMatch("rédéric MART").build()));
+ }
+
+ static Stream<Arguments> notEqualsTestSuite() {
+ return Stream.concat(
+ notContainsTestSuite(),
+ containsArguments());
+ }
+
+ static Stream<Arguments> notContainsTestSuite() {
+ return StreamUtils.flatten(
+ Stream.of(FROM, TO, CC)
+ .flatMap(headerField -> Stream.of(
+ argumentBuilder(headerField)
+ .description("normal content")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(headerField)
+ .description("multiple headers")
+ .headerForField(USER_1_FULL_ADDRESS)
+ .from(USER_2_FULL_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(headerField)
+ .description("scrambled content")
+ .headerForField(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(headerField)
+ .description("folded content")
+ .headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(headerField)
+ .description("empty content")
+ .headerForField(EMPTY)
+ .valueToMatch(SHOULD_NOT_MATCH))
+ .map(FilteringArgumentBuilder::build)),
+ Stream.of(TO_HEADER, CC_HEADER)
+ .flatMap(headerName -> Stream.of(
+ argumentBuilder()
+ .description("normal content " + headerName + " header")
+ .field(RECIPIENT).header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH)
+ .build(),
+ argumentBuilder()
+ .description("scrambled content in " + headerName + " header")
+ .field(RECIPIENT).header(headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH)
+ .build(),
+ argumentBuilder()
+ .description("folded content in " + headerName + " header")
+ .field(RECIPIENT)
+ .header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH)
+ .build(),
+ argumentBuilder()
+ .description("bcc header")
+ .field(RECIPIENT)
+ .header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH)
+ .build())),
+ Stream.of(
+ argumentBuilder().description("multiple to and cc headers").field(RECIPIENT)
+ .ccRecipient(USER_1_FULL_ADDRESS)
+ .ccRecipient(USER_2_FULL_ADDRESS)
+ .toRecipient(USER_3_FULL_ADDRESS)
+ .toRecipient(USER_4_FULL_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH)
+ .build(),
+ argumentBuilder().description("matching bcc headers").field(RECIPIENT)
+ .bccRecipient(USER_1_FULL_ADDRESS)
+ .valueToMatch(USER_1_FULL_ADDRESS)
+ .build(),
+ argumentBuilder().scrambledSubjectToMatch(SHOULD_NOT_MATCH).build(),
+ argumentBuilder().scrambledSubjectShouldNotMatchCaseSensitive().build(),
+ argumentBuilder().unscrambledSubjectToMatch(SHOULD_NOT_MATCH).build(),
+ argumentBuilder().unscrambledSubjectShouldNotMatchCaseSensitive().build()),
+ Stream.of(Rule.Condition.Field.values())
+ .map(field -> argumentBuilder()
+ .description("no header")
+ .field(field)
+ .noHeader()
+ .valueToMatch(USER_1_USERNAME)
+ .build()));
+ }
+
+ @ParameterizedTest(name = "CONTAINS should match for header field {1}, with {0}")
+ @MethodSource("containsTestSuite")
+ void matchingContainsTest(String testDescription,
+ Rule.Condition.Field fieldToMatch,
+ MimeMessageBuilder mimeMessageBuilder,
+ String valueToMatch,
+ JMAPFilteringTestSystem testSystem) throws Exception {
+
+ testSystem.defineRulesForRecipient1(Rule.Condition.of(fieldToMatch, CONTAINS, valueToMatch));
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder);
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isEqualTo(RECIPIENT_1_MAILBOX_1);
+ }
+
+ @ParameterizedTest(name = "CONTAINS should not match for header field {1}, with {0}")
+ @MethodSource("notContainsTestSuite")
+ void notMatchingContainsTest(String testDescription,
+ Rule.Condition.Field fieldToMatch,
+ MimeMessageBuilder mimeMessageBuilder,
+ String valueToMatch,
+ JMAPFilteringTestSystem testSystem) throws Exception {
+
+ testSystem.defineRulesForRecipient1(Rule.Condition.of(fieldToMatch, CONTAINS, valueToMatch));
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder);
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isNull();
+ }
+
+ @ParameterizedTest(name = "NOT-CONTAINS should be matching for field {1}, with {0}")
+ @MethodSource("notContainsTestSuite")
+ void matchingNotContainsTest(String testDescription,
+ Rule.Condition.Field fieldToMatch,
+ MimeMessageBuilder mimeMessageBuilder,
+ String valueToMatch,
+ JMAPFilteringTestSystem testSystem) throws Exception {
+ testSystem.defineRulesForRecipient1(Rule.Condition.of(fieldToMatch, NOT_CONTAINS, valueToMatch));
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder);
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isEqualTo(RECIPIENT_1_MAILBOX_1);
+ }
+
+
+ @ParameterizedTest(name = "NOT-CONTAINS should not be matching for field {1}, with {0}")
+ @MethodSource("containsTestSuite")
+ void notContainsNotMatchingTest(String testDescription,
+ Rule.Condition.Field fieldToMatch,
+ MimeMessageBuilder mimeMessageBuilder,
+ String valueToMatch,
+ JMAPFilteringTestSystem testSystem) throws Exception {
+
+ testSystem.defineRulesForRecipient1(Rule.Condition.of(fieldToMatch, NOT_CONTAINS, valueToMatch));
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder);
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isNull();
+ }
+
+ @ParameterizedTest(name = "EXACTLY-EQUALS should match for header field {1}, with {0}")
+ @MethodSource("exactlyEqualsTestSuite")
+ void equalsMatchingTest(String testDescription,
+ Rule.Condition.Field fieldToMatch,
+ MimeMessageBuilder mimeMessageBuilder,
+ String valueToMatch,
+ JMAPFilteringTestSystem testSystem) throws Exception {
+
+ testSystem.defineRulesForRecipient1(Rule.Condition.of(fieldToMatch, EXACTLY_EQUALS, valueToMatch));
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder);
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isEqualTo(RECIPIENT_1_MAILBOX_1);
+ }
+
+ @ParameterizedTest(name = "EXACTLY-EQUALS should not match for header field {1}, with {0}")
+ @MethodSource("notEqualsTestSuite")
+ void equalsNotMatchingTest(String testDescription,
+ Rule.Condition.Field fieldToMatch,
+ MimeMessageBuilder mimeMessageBuilder,
+ String valueToMatch,
+ JMAPFilteringTestSystem testSystem) throws Exception {
+ testSystem.defineRulesForRecipient1(Rule.Condition.of(fieldToMatch, EXACTLY_EQUALS, valueToMatch));
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder);
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isNull();
+ }
+
+ @ParameterizedTest(name = "NOT_EXACTLY_EQUALS should match for header field {1}, with {0}")
+ @MethodSource("notEqualsTestSuite")
+ void notEqualsMatchingTest(String testDescription,
+ Rule.Condition.Field fieldToMatch,
+ MimeMessageBuilder mimeMessageBuilder,
+ String valueToMatch,
+ JMAPFilteringTestSystem testSystem) throws Exception {
+
+ testSystem.defineRulesForRecipient1(Rule.Condition.of(fieldToMatch, NOT_EXACTLY_EQUALS, valueToMatch));
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder);
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isEqualTo(RECIPIENT_1_MAILBOX_1);
+ }
+
+ @ParameterizedTest(name = "NOT_EXACTLY_EQUALS should not match for header field {1}, with {0}")
+ @MethodSource("exactlyEqualsTestSuite")
+ void notMatchingNotEqualsTests(String testDescription,
+ Rule.Condition.Field fieldToMatch,
+ MimeMessageBuilder mimeMessageBuilder,
+ String valueToMatch,
+ JMAPFilteringTestSystem testSystem) throws Exception {
+ testSystem.defineRulesForRecipient1(Rule.Condition.of(fieldToMatch, NOT_EXACTLY_EQUALS, valueToMatch));
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder);
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isNull();
+ }
+
+ @Nested
+ class MultiRuleBehaviourTest {
+ @Test
+ void mailDirectiveShouldSetFirstMatchedRuleWhenMultipleRules(JMAPFilteringTestSystem testSystem) throws Exception {
+ InMemoryMailboxManager mailboxManager = testSystem.getMailboxManager();
+ MailboxId mailbox1Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_1");
+ MailboxId mailbox2Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_2");
+ MailboxId mailbox3Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_3");
+
+ testSystem.defineRulesForRecipient1();
+ testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
+ ImmutableList.of(
+ Rule.builder()
+ .id(Rule.Id.of("1"))
+ .name("rule 1")
+ .condition(Rule.Condition.of(SUBJECT, CONTAINS, UNSCRAMBLED_SUBJECT))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(mailbox1Id.serialize())))
+ .build(),
+ Rule.builder()
+ .id(Rule.Id.of("2"))
+ .name("rule 2")
+ .condition(Rule.Condition.of(FROM, NOT_CONTAINS, USER_1_USERNAME))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(mailbox2Id.serialize())))
+ .build(),
+ Rule.builder()
+ .id(Rule.Id.of("3"))
+ .name("rule 3")
+ .condition(Rule.Condition.of(TO, EXACTLY_EQUALS, USER_3_ADDRESS))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(mailbox3Id.serialize())))
+ .build()));
+
+ FakeMail mail = FakeMail.builder()
+ .sender(USER_1_ADDRESS)
+ .recipients(RECIPIENT_1)
+ .mimeMessage(mimeMessageBuilder()
+ .addFrom(USER_2_ADDRESS)
+ .addToRecipient(USER_3_ADDRESS)
+ .setSubject(UNSCRAMBLED_SUBJECT))
+ .build();
+
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isEqualTo("RECIPIENT_1_MAILBOX_1");
+ }
+
+ @Test
+ void mailDirectiveShouldSetFirstMatchedMailboxWhenMultipleMailboxes(JMAPFilteringTestSystem testSystem) throws Exception {
+ InMemoryMailboxManager mailboxManager = testSystem.getMailboxManager();
+ MailboxId mailbox1Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_1");
+ MailboxId mailbox2Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_2");
+ MailboxId mailbox3Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_3");
+
+ testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
+ ImmutableList.of(
+ Rule.builder()
+ .id(Rule.Id.of("1"))
+ .name("rule 1")
+ .condition(Rule.Condition.of(SUBJECT, CONTAINS, UNSCRAMBLED_SUBJECT))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(ImmutableList.of(
+ mailbox3Id.serialize(),
+ mailbox2Id.serialize(),
+ mailbox1Id.serialize()))))
+ .build()));
+
+ FakeMail mail = FakeMail.builder()
+ .sender(USER_1_ADDRESS)
+ .recipients(RECIPIENT_1)
+ .mimeMessage(mimeMessageBuilder()
+ .setSubject(UNSCRAMBLED_SUBJECT))
+ .build();
+
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isEqualTo("RECIPIENT_1_MAILBOX_3");
+ }
+
+ @Test
+ void mailDirectiveShouldNotBeSetWhenAllDoNotExactlyEqualsRuleValue(JMAPFilteringTestSystem testSystem) throws Exception {
+ testSystem.defineRulesForRecipient1(
+ Rule.Condition.of(FROM, CONTAINS, USER_1_FULL_ADDRESS),
+ Rule.Condition.of(FROM, EXACTLY_EQUALS, USER_1_FULL_ADDRESS),
+ Rule.Condition.of(TO, CONTAINS, USER_1_FULL_ADDRESS),
+ Rule.Condition.of(TO, EXACTLY_EQUALS, USER_1_FULL_ADDRESS),
+ Rule.Condition.of(CC, CONTAINS, USER_1_FULL_ADDRESS),
+ Rule.Condition.of(CC, EXACTLY_EQUALS, USER_1_FULL_ADDRESS),
+ Rule.Condition.of(RECIPIENT, EXACTLY_EQUALS, USER_1_FULL_ADDRESS),
+ Rule.Condition.of(RECIPIENT, EXACTLY_EQUALS, USER_1_FULL_ADDRESS),
+ Rule.Condition.of(SUBJECT, CONTAINS, USER_1_FULL_ADDRESS),
+ Rule.Condition.of(SUBJECT, EXACTLY_EQUALS, USER_1_FULL_ADDRESS)
+ );
+
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder());
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isNull();
+ }
+
+ @Test
+ void mailDirectiveShouldNotBeSetWhenNoneRulesValueIsContained(JMAPFilteringTestSystem testSystem) throws Exception {
+
+ testSystem.defineRulesForRecipient1(
+ Rule.Condition.of(FROM, CONTAINS, SHOULD_NOT_MATCH),
+ Rule.Condition.of(TO, CONTAINS, SHOULD_NOT_MATCH),
+ Rule.Condition.of(CC, CONTAINS, SHOULD_NOT_MATCH));
+
+ FakeMail mail = FakeMail.builder()
+ .sender(USER_1_ADDRESS)
+ .recipients(RECIPIENT_1)
+ .mimeMessage(mimeMessageBuilder()
+ .addFrom(USER_1_FULL_ADDRESS)
+ .addToRecipient(USER_2_FULL_ADDRESS)
+ .addCcRecipient(USER_3_FULL_ADDRESS))
+ .build();
+
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isNull();
+ }
+ }
+}
\ 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
[13/26] james-project git commit: JAMES-2529 Factorize RECIPIENT
tests with other fields
Posted by ad...@apache.org.
JAMES-2529 Factorize RECIPIENT tests with other fields
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c6a6e976
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c6a6e976
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c6a6e976
Branch: refs/heads/master
Commit: c6a6e9769bb0953fdb3e5781d865296dd700c12c
Parents: 8b1c70a
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 13:57:16 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:03 2018 +0200
----------------------------------------------------------------------
.../jmap/mailet/filter/JMAPFilteringTest.java | 322 ++++++-------------
1 file changed, 106 insertions(+), 216 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/c6a6e976/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
index 29d6bca..0aed4e4 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
@@ -31,7 +31,6 @@ import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.SUBJECT;
import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.TO;
import static org.apache.james.jmap.mailet.filter.ActionApplier.DELIVERY_PATH_PREFIX;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.BOU;
-import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.CC_HEADER;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.EMPTY;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.FRED_MARTIN_FULLNAME;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.FRED_MARTIN_FULL_SCRAMBLED_ADDRESS;
@@ -40,7 +39,6 @@ import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1_USERNAME;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.SCRAMBLED_SUBJECT;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.SHOULD_NOT_MATCH;
-import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.TO_HEADER;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.UNFOLDED_USERNAME;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.UNSCRAMBLED_SUBJECT;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_1_ADDRESS;
@@ -51,7 +49,6 @@ import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_2_AD
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_2_FULL_ADDRESS;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_3_ADDRESS;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_3_FULL_ADDRESS;
-import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_3_USERNAME;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_4_FULL_ADDRESS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
@@ -63,9 +60,11 @@ import java.util.stream.Stream;
import org.apache.james.core.User;
import org.apache.james.core.builder.MimeMessageBuilder;
import org.apache.james.jmap.api.filtering.Rule;
+import org.apache.james.jmap.api.filtering.Rule.Condition.Field;
import org.apache.james.jmap.mailet.filter.JMAPFilteringExtension.JMAPFilteringTestSystem;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.util.StreamUtils;
+import org.apache.mailet.base.RFC2822Headers;
import org.apache.mailet.base.test.FakeMail;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -133,13 +132,6 @@ class JMAPFilteringTest {
return this;
}
- public FilteringArgumentBuilder headerForField(String headerValue) {
- Preconditions.checkState(field.isPresent(), "field should be set first");
-
- mimeMessageBuilder.addHeader(field.get().asString(), headerValue);
- return this;
- }
-
public FilteringArgumentBuilder subject(String subject) {
mimeMessageBuilder.setSubject(subject);
return this;
@@ -197,121 +189,97 @@ class JMAPFilteringTest {
.field(field);
}
+ static class FieldAndHeader {
+ private final Rule.Condition.Field field;
+ private final String headerName;
+
+ public FieldAndHeader(Rule.Condition.Field field, String headerName) {
+ this.field = field;
+ this.headerName = headerName;
+ }
+ }
+
+ public static final ImmutableList<FieldAndHeader> ADDRESS_TESTING_COMBINATION = ImmutableList.of(
+ new FieldAndHeader(Field.FROM, RFC2822Headers.FROM),
+ new FieldAndHeader(Field.TO, RFC2822Headers.TO),
+ new FieldAndHeader(Field.CC, RFC2822Headers.CC),
+ new FieldAndHeader(Field.RECIPIENT, RFC2822Headers.TO),
+ new FieldAndHeader(Field.RECIPIENT, RFC2822Headers.CC));
+
static Stream<Arguments> exactlyEqualsTestSuite() {
return StreamUtils.flatten(
- Stream.of(FROM, TO, CC)
- .flatMap(headerField -> Stream.of(
- argumentBuilder(headerField)
+ ADDRESS_TESTING_COMBINATION
+ .stream()
+ .flatMap(fieldAndHeader -> Stream.of(
+ argumentBuilder(fieldAndHeader.field)
.description("full address value")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch(USER_1_USERNAME),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("full address value (different case)")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch(USER_1_USERNAME.toUpperCase(Locale.ENGLISH)),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("address only value")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch(USER_1_ADDRESS),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("address only value (different case)")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch(USER_1_ADDRESS.toUpperCase(Locale.ENGLISH)),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("personal only value")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch(USER_1_FULL_ADDRESS),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("personal only value (different case)")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch(USER_1_FULL_ADDRESS.toUpperCase()),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("personal header should match personal")
- .headerForField(USER_1_USERNAME)
+ .header(fieldAndHeader.headerName, USER_1_USERNAME)
.valueToMatch(USER_1_USERNAME),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("address header should match address")
- .headerForField(USER_1_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_ADDRESS)
.valueToMatch(USER_1_ADDRESS),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("multiple headers")
- .headerForField(USER_1_FULL_ADDRESS)
- .headerForField(USER_2_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_2_FULL_ADDRESS)
.valueToMatch(USER_1_USERNAME),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("scrambled content")
- .headerForField(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
+ .header(fieldAndHeader.headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
.valueToMatch(FRED_MARTIN_FULLNAME),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("folded content")
- .headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
.valueToMatch(UNFOLDED_USERNAME),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("folded content (different case)")
- .headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
.valueToMatch(UNFOLDED_USERNAME.toUpperCase()),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid address, personal match")
- .headerForField("Benoit <invalid>")
+ .header(fieldAndHeader.headerName, "Benoit <invalid>")
.valueToMatch("Benoit"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid address, address match")
- .headerForField("Benoit <invalid>")
+ .header(fieldAndHeader.headerName, "Benoit <invalid>")
.valueToMatch("invalid"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid address, full match")
- .headerForField("Benoit <invalid>")
+ .header(fieldAndHeader.headerName, "Benoit <invalid>")
.valueToMatch("Benoit <invalid>"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid header, full match")
- .headerForField("Benoit <invalid")
+ .header(fieldAndHeader.headerName, "Benoit <invalid")
.valueToMatch("Benoit <invalid")
).map(FilteringArgumentBuilder::build)),
- Stream.of(TO_HEADER, CC_HEADER)
- .flatMap(headerName -> Stream.of(
- argumentBuilder(RECIPIENT)
- .description("full address " + headerName + " header")
- .header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(USER_3_FULL_ADDRESS),
- argumentBuilder(RECIPIENT)
- .description("full address " + headerName + " header (different case)")
- .header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(USER_3_FULL_ADDRESS.toUpperCase(Locale.ENGLISH)),
- argumentBuilder(RECIPIENT)
- .description("address only " + headerName + " header")
- .header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(USER_3_ADDRESS),
- argumentBuilder(RECIPIENT)
- .description("personal only " + headerName + " header")
- .header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(USER_3_USERNAME),
- argumentBuilder(RECIPIENT)
- .description("scrambled content in " + headerName + " header")
- .header(headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
- .valueToMatch(FRED_MARTIN_FULLNAME),
- argumentBuilder(RECIPIENT)
- .description("folded content in " + headerName + " header")
- .header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
- .valueToMatch(UNFOLDED_USERNAME),
- argumentBuilder(RECIPIENT)
- .description("invalid " + headerName + " address, personal match")
- .header(headerName, "Benoit <invalid>")
- .valueToMatch("Benoit"),
- argumentBuilder(RECIPIENT)
- .description("invalid " + headerName + " address, address match")
- .header(headerName, "Benoit <invalid>")
- .valueToMatch("invalid"),
- argumentBuilder(RECIPIENT)
- .description("invalid " + headerName + " address, full match")
- .header(headerName, "Benoit <invalid>")
- .valueToMatch("Benoit <invalid>"),
- argumentBuilder(RECIPIENT)
- .description("invalid " + headerName + ", full match")
- .header(headerName, "Benoit <invalid")
- .valueToMatch("Benoit <invalid"))
- .map(FilteringArgumentBuilder::build)),
Stream.of(
- argumentBuilder().description("multiple to and cc headers").field(RECIPIENT)
+ argumentBuilder().description("multiple to and cc headers")
+ .field(RECIPIENT)
.ccRecipient(USER_1_FULL_ADDRESS)
.ccRecipient(USER_2_FULL_ADDRESS)
.toRecipient(USER_3_FULL_ADDRESS)
@@ -330,119 +298,68 @@ class JMAPFilteringTest {
private static Stream<Arguments> containsArguments() {
return StreamUtils.flatten(
- Stream.of(FROM, TO, CC)
- .flatMap(headerField -> Stream.of(
- argumentBuilder(headerField)
+ ADDRESS_TESTING_COMBINATION.stream()
+ .flatMap(fieldAndHeader -> Stream.of(
+ argumentBuilder(fieldAndHeader.field)
.description("full address value (partial matching)")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch("ser1 <"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("full address value (partial matching, different case)")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch("SER1 <"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("address only value (partial matching)")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch("ser1@jam"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("personal only value (partial matching)")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName,USER_1_FULL_ADDRESS)
.valueToMatch("ser1"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("address header & match in the address (partial matching)")
- .headerForField(USER_1_ADDRESS)
+ .header(fieldAndHeader.headerName,USER_1_ADDRESS)
.valueToMatch("ser1@jam"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("raw value matching (partial matching)")
- .headerForField(GA_BOU_ZO_MEU_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName,GA_BOU_ZO_MEU_FULL_ADDRESS)
.valueToMatch(BOU),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("multiple headers (partial matching)")
- .headerForField(USER_1_FULL_ADDRESS)
- .headerForField(USER_2_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName,USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName,USER_2_FULL_ADDRESS)
.valueToMatch("ser1@jam"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("scrambled content (partial matching)")
- .headerForField(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
+ .header(fieldAndHeader.headerName,FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
.valueToMatch("déric MAR"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("folded content (partial matching)")
- .headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName,USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
.valueToMatch("ded_us"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid address, personal match (partial matching)")
- .headerForField("Benoit <invalid>")
+ .header(fieldAndHeader.headerName,"Benoit <invalid>")
.valueToMatch("enoi"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid address, address match (partial matching)")
- .headerForField("Benoit <invalid>")
+ .header(fieldAndHeader.headerName,"Benoit <invalid>")
.valueToMatch("nvali"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid address, full match (partial matching)")
- .headerForField("Benoit <invalid>")
+ .header(fieldAndHeader.headerName,"Benoit <invalid>")
.valueToMatch("enoit <invali"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid header, full match (partial matching)")
- .headerForField("Benoit <invalid")
+ .header(fieldAndHeader.headerName,"Benoit <invalid")
.valueToMatch("enoit <invali"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid header, personal match (partial matching)")
- .headerForField("Benoit <invalid")
+ .header(fieldAndHeader.headerName,"Benoit <invalid")
.valueToMatch("enoi"),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid header, address match (partial matching)")
- .headerForField("Benoit <invalid")
- .valueToMatch("nvali"))
- .map(FilteringArgumentBuilder::build)),
- Stream.of(TO_HEADER, CC_HEADER)
- .flatMap(headerName -> Stream.of(
- argumentBuilder(RECIPIENT)
- .description("full address " + headerName + " header (partial matching)")
- .header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch("ser3 <us"),
- argumentBuilder(RECIPIENT)
- .description("full address " + headerName + " header (partial matching, different case)")
- .header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch("SER3 <US"),
- argumentBuilder(RECIPIENT)
- .description("address only " + headerName + " header (partial matching)")
- .header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch("ser3@jam"),
- argumentBuilder(RECIPIENT)
- .description("personal only " + headerName + " header (partial matching)")
- .header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch("ser3"),
- argumentBuilder(RECIPIENT)
- .description("scrambled content in " + headerName + " header (partial matching)")
- .header(headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
- .valueToMatch("déric MAR"),
- argumentBuilder(RECIPIENT)
- .description("folded content in " + headerName + " header (partial matching)")
- .header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
- .valueToMatch("folded_us"),
- argumentBuilder(RECIPIENT)
- .description("invalid address, personal match (partial matching)")
- .header(headerName, "Benoit <invalid>")
- .valueToMatch("enoi"),
- argumentBuilder(RECIPIENT)
- .description("invalid address, address match (partial matching)")
- .header(headerName, "Benoit <invalid>")
- .valueToMatch("nvali"),
- argumentBuilder(RECIPIENT)
- .description("invalid address, full match (partial matching)")
- .header(headerName, "Benoit <invalid>")
- .valueToMatch("enoit <invali"),
- argumentBuilder(RECIPIENT)
- .description("invalid header, full match (partial matching)")
- .header(headerName, "Benoit <invalid")
- .valueToMatch("enoit <invali"),
- argumentBuilder(RECIPIENT)
- .description("invalid header, personal match (partial matching)")
- .header(headerName, "Benoit <invalid")
- .valueToMatch("enoi"),
- argumentBuilder(RECIPIENT)
- .description("invalid header, address match (partial matching)")
- .header(headerName, "Benoit <invalid")
+ .header(fieldAndHeader.headerName,"Benoit <invalid")
.valueToMatch("nvali"))
.map(FilteringArgumentBuilder::build)),
Stream.of(
@@ -464,63 +381,36 @@ class JMAPFilteringTest {
static Stream<Arguments> notContainsTestSuite() {
return StreamUtils.flatten(
- Stream.of(FROM, TO, CC)
- .flatMap(headerField -> Stream.of(
- argumentBuilder(headerField)
+ ADDRESS_TESTING_COMBINATION.stream()
+ .flatMap(fieldAndHeader -> Stream.of(
+ argumentBuilder(fieldAndHeader.field)
.description("normal content")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("multiple headers")
- .headerForField(USER_1_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_FULL_ADDRESS)
.from(USER_2_FULL_ADDRESS)
.valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("scrambled content")
- .headerForField(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
+ .header(fieldAndHeader.headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
.valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("folded content")
- .headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
.valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(headerField)
+ argumentBuilder(fieldAndHeader.field)
.description("empty content")
- .headerForField(EMPTY)
- .valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(headerField)
- .description("invalid address, personal match")
- .headerForField("Benoit <invalid>")
- .valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(headerField)
- .description("invalid header, full match")
- .headerForField("Benoit <invalid")
- .valueToMatch(SHOULD_NOT_MATCH))
- .map(FilteringArgumentBuilder::build)),
- Stream.of(TO_HEADER, CC_HEADER)
- .flatMap(headerName -> Stream.of(
- argumentBuilder(RECIPIENT)
- .description("normal content " + headerName + " header")
- .header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(RECIPIENT)
- .description("scrambled content in " + headerName + " header")
- .field(RECIPIENT).header(headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
- .valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(RECIPIENT)
- .description("folded content in " + headerName + " header")
- .header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
- .valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(RECIPIENT)
- .description("bcc header")
- .header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
+ .header(fieldAndHeader.headerName, EMPTY)
.valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(RECIPIENT)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid address, personal match")
- .header(headerName, "Benoit <invalid>")
+ .header(fieldAndHeader.headerName, "Benoit <invalid>")
.valueToMatch(SHOULD_NOT_MATCH),
- argumentBuilder(RECIPIENT)
+ argumentBuilder(fieldAndHeader.field)
.description("invalid header, full match")
- .header(headerName, "Benoit <invalid")
+ .header(fieldAndHeader.headerName, "Benoit <invalid")
.valueToMatch(SHOULD_NOT_MATCH))
.map(FilteringArgumentBuilder::build)),
Stream.of(
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[11/26] james-project git commit: JAMES-2529 Remove .orElse(null)
Posted by ad...@apache.org.
JAMES-2529 Remove .orElse(null)
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b62bc554
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b62bc554
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b62bc554
Branch: refs/heads/master
Commit: b62bc554ddb3c31556b0a8ca33124274c878ca18
Parents: e06fb4a
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 10:21:37 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:02 2018 +0200
----------------------------------------------------------------------
.../java/org/apache/james/jmap/mailet/filter/MailMatcher.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/b62bc554/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index aea0b75..410146e 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -133,9 +133,9 @@ public interface MailMatcher {
ContentMatcher ADDRESS_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents
.map(ContentMatcher::asAddressHeader)
.anyMatch(addressHeader ->
- StringUtils.equalsIgnoreCase(addressHeader.getFullAddress(), valueToMatch)
- || StringUtils.equalsIgnoreCase(addressHeader.getAddress().orElse(null), valueToMatch)
- || StringUtils.equalsIgnoreCase(addressHeader.getPersonal().orElse(null), valueToMatch));
+ valueToMatch.equalsIgnoreCase(addressHeader.getFullAddress())
+ || addressHeader.getAddress().map(valueToMatch::equalsIgnoreCase).orElse(false)
+ || addressHeader.getPersonal().map(valueToMatch::equalsIgnoreCase).orElse(false));
ContentMatcher ADDRESS_NOT_EXACTLY_EQUALS_MATCHER = negate(ADDRESS_EXACTLY_EQUALS_MATCHER);
Map<Rule.Condition.Comparator, ContentMatcher> HEADER_ADDRESS_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[25/26] james-project git commit: JAMES-2529 JMAP filtering mailet
should be compulsory
Posted by ad...@apache.org.
JAMES-2529 JMAP filtering mailet should be compulsory
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/9ba6a1dd
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/9ba6a1dd
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/9ba6a1dd
Branch: refs/heads/master
Commit: 9ba6a1dd270f99735c7f9d3d4b2adb5076583c10
Parents: 808c8fa
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Aug 29 12:36:24 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:11:55 2018 +0200
----------------------------------------------------------------------
.../src/test/resources/mailetcontainer.xml | 1 +
.../sample-configuration/mailetcontainer.xml | 1 +
.../src/test/resources/mailetcontainer.xml | 1 +
.../java/org/apache/james/jmap/JMAPModule.java | 8 +++-
.../resources/defaultJmapMailetContainer.xml | 1 +
.../james/jmap/MailetPreconditionTest.java | 40 ++++++++++++++++++++
6 files changed, 51 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/9ba6a1dd/server/container/cli-integration/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/server/container/cli-integration/src/test/resources/mailetcontainer.xml b/server/container/cli-integration/src/test/resources/mailetcontainer.xml
index f14a335..cb2c0dc 100644
--- a/server/container/cli-integration/src/test/resources/mailetcontainer.xml
+++ b/server/container/cli-integration/src/test/resources/mailetcontainer.xml
@@ -58,6 +58,7 @@
</mailet>
<mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/>
<mailet match="RecipientIsLocal" class="Sieve"/>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
http://git-wip-us.apache.org/repos/asf/james-project/blob/9ba6a1dd/server/container/guice/memory-guice/sample-configuration/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/sample-configuration/mailetcontainer.xml b/server/container/guice/memory-guice/sample-configuration/mailetcontainer.xml
index a910f1b..6b29c87 100644
--- a/server/container/guice/memory-guice/sample-configuration/mailetcontainer.xml
+++ b/server/container/guice/memory-guice/sample-configuration/mailetcontainer.xml
@@ -59,6 +59,7 @@
<mailet match="All" class="RecipientRewriteTable" />
<mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/>
<mailet match="RecipientIsLocal" class="Sieve"/>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="relay-allowed" class="RemoteDelivery">
http://git-wip-us.apache.org/repos/asf/james-project/blob/9ba6a1dd/server/container/guice/memory-guice/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/test/resources/mailetcontainer.xml b/server/container/guice/memory-guice/src/test/resources/mailetcontainer.xml
index ab279cc..e82f960 100644
--- a/server/container/guice/memory-guice/src/test/resources/mailetcontainer.xml
+++ b/server/container/guice/memory-guice/src/test/resources/mailetcontainer.xml
@@ -65,6 +65,7 @@
<mailet match="IsMarkedAsSpam" class="WithStorageDirective">
<targetFolderName>Spam</targetFolderName>
</mailet>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
http://git-wip-us.apache.org/repos/asf/james-project/blob/9ba6a1dd/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
index 5158d2f..365df71 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
@@ -31,6 +31,7 @@ import org.apache.commons.io.FileUtils;
import org.apache.james.filesystem.api.FileSystem;
import org.apache.james.jmap.event.PropagateLookupRightListener;
import org.apache.james.jmap.mailet.VacationMailet;
+import org.apache.james.jmap.mailet.filter.JMAPFiltering;
import org.apache.james.jmap.methods.RequestHandler;
import org.apache.james.jmap.send.PostDequeueDecoratorFactory;
import org.apache.james.jmap.utils.HtmlTextExtractor;
@@ -76,6 +77,10 @@ public class JMAPModule extends AbstractModule {
new CamelMailetContainerModule.TransportProcessorCheck.Impl(
RecipientIsLocal.class,
VacationMailet.class);
+ public static final CamelMailetContainerModule.TransportProcessorCheck FILTERING_MAILET_CHECK =
+ new CamelMailetContainerModule.TransportProcessorCheck.Impl(
+ RecipientIsLocal.class,
+ JMAPFiltering.class);
@Override
protected void configure() {
@@ -96,7 +101,8 @@ public class JMAPModule extends AbstractModule {
Multibinder<CamelMailetContainerModule.TransportProcessorCheck> transportProcessorChecks = Multibinder.newSetBinder(binder(), CamelMailetContainerModule.TransportProcessorCheck.class);
transportProcessorChecks.addBinding().toInstance(VACATION_MAILET_CHECK);
-
+ transportProcessorChecks.addBinding().toInstance(FILTERING_MAILET_CHECK);
+
bind(SystemMailboxesProvider.class).to(SystemMailboxesProviderImpl.class);
bind(MailQueueItemDecoratorFactory.class).to(PostDequeueDecoratorFactory.class).in(Scopes.SINGLETON);
http://git-wip-us.apache.org/repos/asf/james-project/blob/9ba6a1dd/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml b/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
index ccf6017..4f70e72 100644
--- a/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
+++ b/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
@@ -42,6 +42,7 @@
</mailet>
<mailet match="All" class="RecipientRewriteTable" />
<mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
http://git-wip-us.apache.org/repos/asf/james-project/blob/9ba6a1dd/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
index aaacbd9..6971db3 100644
--- a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
+++ b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
@@ -26,6 +26,7 @@ import java.util.List;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.james.jmap.mailet.VacationMailet;
+import org.apache.james.jmap.mailet.filter.JMAPFiltering;
import org.apache.james.mailetcontainer.impl.MatcherMailetPair;
import org.apache.james.modules.server.CamelMailetContainerModule;
import org.apache.james.transport.mailets.Null;
@@ -84,6 +85,45 @@ class MailetPreconditionTest {
}
@Nested
+ class FilteringMailetCheck {
+ @Test
+ void filteringMailetCheckShouldThrowOnEmptyList() {
+ assertThatThrownBy(() -> JMAPModule.FILTERING_MAILET_CHECK.check(Lists.newArrayList()))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void filteringMailetCheckShouldThrowOnNullList() {
+ assertThatThrownBy(() -> JMAPModule.FILTERING_MAILET_CHECK.check(null))
+ .isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ void filteringMailetCheckShouldThrowOnWrongMatcher() {
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), new JMAPFiltering(null, null, null)));
+
+ assertThatThrownBy(() -> JMAPModule.FILTERING_MAILET_CHECK.check(pairs))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void filteringMailetCheckShouldThrowOnWrongMailet() {
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new Null()));
+
+ assertThatThrownBy(() -> JMAPModule.FILTERING_MAILET_CHECK.check(pairs))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void filteringMailetCheckShouldNotThrowIfValidPairPresent() {
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new JMAPFiltering(null, null, null)));
+
+ assertThatCode(() -> JMAPModule.FILTERING_MAILET_CHECK.check(pairs))
+ .doesNotThrowAnyException();
+ }
+ }
+
+ @Nested
class BccCheck {
@Test
void bccMailetCheckShouldThrowOnEmptyList() {
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[24/26] james-project git commit: JAMES-2529 Configure JMAP filtering
mailet by default
Posted by ad...@apache.org.
JAMES-2529 Configure JMAP filtering mailet by default
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/808c8fa3
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/808c8fa3
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/808c8fa3
Branch: refs/heads/master
Commit: 808c8fa3cf44810481ba7be2f656ece9c50082a3
Parents: 7164031
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Aug 29 12:35:34 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:11:55 2018 +0200
----------------------------------------------------------------------
.../cassandra/package/etc/james/templates/mailetcontainer.xml | 1 +
.../run/guice/cassandra/destination/conf/mailetcontainer.xml | 1 +
.../guice/cassandra-guice/src/test/resources/mailetcontainer.xml | 1 +
.../cassandra-ldap-guice/src/test/resources/mailetcontainer.xml | 1 +
.../org/apache/james/mailets/configuration/CommonProcessors.java | 4 ++++
.../apache/james/transport/mailets/GroupMappingRelayTest.java | 4 ++++
.../org/apache/james/transport/mailets/GroupMappingTest.java | 4 ++++
.../src/test/resources/mailetcontainer.xml | 1 +
8 files changed, 17 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/808c8fa3/dockerfiles/packaging/guice/cassandra/package/etc/james/templates/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/dockerfiles/packaging/guice/cassandra/package/etc/james/templates/mailetcontainer.xml b/dockerfiles/packaging/guice/cassandra/package/etc/james/templates/mailetcontainer.xml
index 681b966..e8200f4 100644
--- a/dockerfiles/packaging/guice/cassandra/package/etc/james/templates/mailetcontainer.xml
+++ b/dockerfiles/packaging/guice/cassandra/package/etc/james/templates/mailetcontainer.xml
@@ -64,6 +64,7 @@
<mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/>
<mailet match="RecipientIsLocal" class="Sieve"/>
<mailet match="RecipientIsLocal" class="AddDeliveredToHeader"/>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
http://git-wip-us.apache.org/repos/asf/james-project/blob/808c8fa3/dockerfiles/run/guice/cassandra/destination/conf/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/dockerfiles/run/guice/cassandra/destination/conf/mailetcontainer.xml b/dockerfiles/run/guice/cassandra/destination/conf/mailetcontainer.xml
index 3839b39..04d0459 100644
--- a/dockerfiles/run/guice/cassandra/destination/conf/mailetcontainer.xml
+++ b/dockerfiles/run/guice/cassandra/destination/conf/mailetcontainer.xml
@@ -66,6 +66,7 @@
<mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/>
<mailet match="RecipientIsLocal" class="Sieve"/>
<mailet match="RecipientIsLocal" class="AddDeliveredToHeader"/>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
http://git-wip-us.apache.org/repos/asf/james-project/blob/808c8fa3/server/container/guice/cassandra-guice/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/resources/mailetcontainer.xml b/server/container/guice/cassandra-guice/src/test/resources/mailetcontainer.xml
index 2365c7c..412e6e9 100644
--- a/server/container/guice/cassandra-guice/src/test/resources/mailetcontainer.xml
+++ b/server/container/guice/cassandra-guice/src/test/resources/mailetcontainer.xml
@@ -74,6 +74,7 @@
<mailet match="IsMarkedAsSpam" class="WithStorageDirective">
<targetFolderName>Spam</targetFolderName>
</mailet>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
http://git-wip-us.apache.org/repos/asf/james-project/blob/808c8fa3/server/container/guice/cassandra-ldap-guice/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-ldap-guice/src/test/resources/mailetcontainer.xml b/server/container/guice/cassandra-ldap-guice/src/test/resources/mailetcontainer.xml
index 4a7d1e8..69d03e2 100644
--- a/server/container/guice/cassandra-ldap-guice/src/test/resources/mailetcontainer.xml
+++ b/server/container/guice/cassandra-ldap-guice/src/test/resources/mailetcontainer.xml
@@ -59,6 +59,7 @@
</mailet>
<mailet match="All" class="RecipientRewriteTable" />
<mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
http://git-wip-us.apache.org/repos/asf/james-project/blob/808c8fa3/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/CommonProcessors.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/CommonProcessors.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/CommonProcessors.java
index 936124f..503b940 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/CommonProcessors.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/CommonProcessors.java
@@ -21,6 +21,7 @@
package org.apache.james.mailets.configuration;
import org.apache.james.jmap.mailet.VacationMailet;
+import org.apache.james.jmap.mailet.filter.JMAPFiltering;
import org.apache.james.mailrepository.api.MailRepositoryUrl;
import org.apache.james.transport.mailets.AddDeliveredToHeader;
import org.apache.james.transport.mailets.Bounce;
@@ -95,6 +96,9 @@ public class CommonProcessors {
.mailet(VacationMailet.class))
.addMailet(MailetConfiguration.builder()
.matcher(RecipientIsLocal.class)
+ .mailet(JMAPFiltering.class))
+ .addMailet(MailetConfiguration.builder()
+ .matcher(RecipientIsLocal.class)
.mailet(Sieve.class))
.addMailet(MailetConfiguration.builder()
.matcher(RecipientIsLocal.class)
http://git-wip-us.apache.org/repos/asf/james-project/blob/808c8fa3/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingRelayTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingRelayTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingRelayTest.java
index 4ba8505..a4de0bb 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingRelayTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingRelayTest.java
@@ -30,6 +30,7 @@ import javax.mail.internet.MimeMessage;
import org.apache.james.core.builder.MimeMessageBuilder;
import org.apache.james.jmap.mailet.VacationMailet;
+import org.apache.james.jmap.mailet.filter.JMAPFiltering;
import org.apache.james.mailets.TemporaryJamesServer;
import org.apache.james.mailets.configuration.CommonProcessors;
import org.apache.james.mailets.configuration.MailetConfiguration;
@@ -100,6 +101,9 @@ public class GroupMappingRelayTest {
.addMailet(MailetConfiguration.builder()
.matcher(RecipientIsLocal.class)
.mailet(VacationMailet.class))
+ .addMailet(MailetConfiguration.builder()
+ .matcher(RecipientIsLocal.class)
+ .mailet(JMAPFiltering.class))
.addMailetsFrom(CommonProcessors.deliverOnlyTransport())
.addMailet(MailetConfiguration.remoteDeliveryBuilder()
.matcher(All.class)
http://git-wip-us.apache.org/repos/asf/james-project/blob/808c8fa3/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
index 7b9dc10..a2ff045 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
@@ -30,6 +30,7 @@ import javax.mail.internet.MimeMessage;
import org.apache.james.core.builder.MimeMessageBuilder;
import org.apache.james.jmap.mailet.VacationMailet;
+import org.apache.james.jmap.mailet.filter.JMAPFiltering;
import org.apache.james.mailbox.model.MailboxConstants;
import org.apache.james.mailets.TemporaryJamesServer;
import org.apache.james.mailets.configuration.CommonProcessors;
@@ -98,6 +99,9 @@ public class GroupMappingTest {
.addMailet(MailetConfiguration.builder()
.matcher(RecipientIsLocal.class)
.mailet(VacationMailet.class))
+ .addMailet(MailetConfiguration.builder()
+ .matcher(RecipientIsLocal.class)
+ .mailet(JMAPFiltering.class))
.addMailetsFrom(CommonProcessors.deliverOnlyTransport()))
.putProcessor(ProcessorConfiguration.builder()
.state(RRT_ERROR)
http://git-wip-us.apache.org/repos/asf/james-project/blob/808c8fa3/server/protocols/webadmin-integration-test/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin-integration-test/src/test/resources/mailetcontainer.xml b/server/protocols/webadmin-integration-test/src/test/resources/mailetcontainer.xml
index f24fd9c..f9d4127 100644
--- a/server/protocols/webadmin-integration-test/src/test/resources/mailetcontainer.xml
+++ b/server/protocols/webadmin-integration-test/src/test/resources/mailetcontainer.xml
@@ -60,6 +60,7 @@
<mailet match="All" class="RecipientRewriteTable" />
<mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/>
<mailet match="RecipientIsLocal" class="Sieve"/>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[19/26] james-project git commit: JAMES-2529 Factorize code for
Transport checks
Posted by ad...@apache.org.
JAMES-2529 Factorize code for Transport checks
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/8382d619
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/8382d619
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/8382d619
Branch: refs/heads/master
Commit: 8382d61981e89c6d2387734aacd18aa57a456670
Parents: 472bf31
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Aug 29 12:20:32 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:11:54 2018 +0200
----------------------------------------------------------------------
.../server/CamelMailetContainerModule.java | 56 +++++++++++++++-----
.../java/org/apache/james/jmap/JMAPModule.java | 19 ++-----
.../james/jmap/MailetPreconditionTest.java | 22 ++++----
3 files changed, 59 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/8382d619/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
index 0d41d59..92fd1a5 100644
--- a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
+++ b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
@@ -22,6 +22,7 @@ package org.apache.james.modules.server;
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import java.util.function.Predicate;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.SimpleRegistry;
@@ -50,7 +51,9 @@ import org.apache.james.utils.GuiceMatcherLoader;
import org.apache.james.utils.GuiceProbe;
import org.apache.james.utils.MailetConfigurationOverride;
import org.apache.james.utils.SpoolerProbe;
+import org.apache.mailet.Mailet;
import org.apache.mailet.MailetContext;
+import org.apache.mailet.Matcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -67,6 +70,12 @@ public class CamelMailetContainerModule extends AbstractModule {
private static final Logger LOGGER = LoggerFactory.getLogger(CamelMailetContainerModule.class);
+ public static final TransportProcessorCheck.Impl BCC_Check = new TransportProcessorCheck.Impl(
+ All.class,
+ RemoveMimeHeader.class,
+ pair -> pair.getMailet().getMailetConfig().getInitParameter("name").equals("bcc"),
+ "Should be configured to remove Bcc header");
+
@Override
protected void configure() {
bind(CamelCompositeProcessor.class).in(Scopes.SINGLETON);
@@ -85,7 +94,7 @@ public class CamelMailetContainerModule extends AbstractModule {
Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(MailetModuleConfigurationPerformer.class);
Multibinder<CamelMailetContainerModule.TransportProcessorCheck> transportProcessorChecks = Multibinder.newSetBinder(binder(), CamelMailetContainerModule.TransportProcessorCheck.class);
- transportProcessorChecks.addBinding().to(BccMailetCheck.class);
+ transportProcessorChecks.addBinding().toInstance(BCC_Check);
}
@Provides
@@ -215,18 +224,39 @@ public class CamelMailetContainerModule extends AbstractModule {
@FunctionalInterface
public interface TransportProcessorCheck {
void check(List<MatcherMailetPair> pairs) throws ConfigurationException;
- }
-
- public static class BccMailetCheck implements CamelMailetContainerModule.TransportProcessorCheck {
- @Override
- public void check(List<MatcherMailetPair> pairs) throws ConfigurationException {
- Preconditions.checkNotNull(pairs);
- pairs.stream()
- .filter(pair -> pair.getMailet().getClass().equals(RemoveMimeHeader.class))
- .filter(pair -> pair.getMatcher().getClass().equals(All.class))
- .filter(pair -> pair.getMailet().getMailetConfig().getInitParameter("name").equals("bcc"))
- .findAny()
- .orElseThrow(() -> new ConfigurationException("Missing RemoveMimeHeader in mailets configuration (mailetcontainer -> processors -> transport). Should be configured to remove Bcc header"));
+
+ class Impl implements TransportProcessorCheck {
+ private final Class<? extends Matcher> matcherClass;
+ private final Class<? extends Mailet> mailetClass;
+ private final Optional<Predicate<? super MatcherMailetPair>> additionalFilter;
+ private final Optional<String> additionalErrorMessage;
+
+ public Impl(Class<? extends Matcher> matcherClass, Class<? extends Mailet> mailetClass) {
+ this(matcherClass, mailetClass, Optional.empty(), Optional.empty());
+ }
+
+ public Impl(Class<? extends Matcher> matcherClass, Class<? extends Mailet> mailetClass, Predicate<? super MatcherMailetPair> additionalFilter, String additionalErrorMessage) {
+ this(matcherClass, mailetClass, Optional.of(additionalFilter), Optional.of(additionalErrorMessage));
+ }
+
+ private Impl(Class<? extends Matcher> matcherClass, Class<? extends Mailet> mailetClass, Optional<Predicate<? super MatcherMailetPair>> additionalFilter, Optional<String> additionalErrorMessage) {
+ this.matcherClass = matcherClass;
+ this.mailetClass = mailetClass;
+ this.additionalFilter = additionalFilter;
+ this.additionalErrorMessage = additionalErrorMessage;
+ }
+
+ @Override
+ public void check(List<MatcherMailetPair> pairs) throws ConfigurationException {
+ Preconditions.checkNotNull(pairs);
+ pairs.stream()
+ .filter(pair -> pair.getMailet().getClass().equals(mailetClass))
+ .filter(pair -> pair.getMatcher().getClass().equals(matcherClass))
+ .filter(additionalFilter.orElse(any -> true))
+ .findAny()
+ .orElseThrow(() -> new ConfigurationException("Missing " + mailetClass.getName() + " in mailets configuration (mailetcontainer -> processors -> transport). " +
+ additionalErrorMessage.orElse("")));
+ }
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/8382d619/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
index b70c953..5158d2f 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
@@ -42,7 +42,6 @@ import org.apache.james.lifecycle.api.Configurable;
import org.apache.james.mailbox.MailboxListener;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
-import org.apache.james.mailetcontainer.impl.MatcherMailetPair;
import org.apache.james.modules.server.CamelMailetContainerModule;
import org.apache.james.queue.api.MailQueueItemDecoratorFactory;
import org.apache.james.server.core.configuration.FileConfigurationProvider;
@@ -73,6 +72,10 @@ public class JMAPModule extends AbstractModule {
throw new RuntimeException(e);
}
};
+ public static final CamelMailetContainerModule.TransportProcessorCheck VACATION_MAILET_CHECK =
+ new CamelMailetContainerModule.TransportProcessorCheck.Impl(
+ RecipientIsLocal.class,
+ VacationMailet.class);
@Override
protected void configure() {
@@ -92,7 +95,7 @@ public class JMAPModule extends AbstractModule {
Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(RequiredCapabilitiesPrecondition.class);
Multibinder<CamelMailetContainerModule.TransportProcessorCheck> transportProcessorChecks = Multibinder.newSetBinder(binder(), CamelMailetContainerModule.TransportProcessorCheck.class);
- transportProcessorChecks.addBinding().to(VacationMailetCheck.class);
+ transportProcessorChecks.addBinding().toInstance(VACATION_MAILET_CHECK);
bind(SystemMailboxesProvider.class).to(SystemMailboxesProviderImpl.class);
bind(MailQueueItemDecoratorFactory.class).to(PostDequeueDecoratorFactory.class).in(Scopes.SINGLETON);
@@ -166,16 +169,4 @@ public class JMAPModule extends AbstractModule {
}
}
- public static class VacationMailetCheck implements CamelMailetContainerModule.TransportProcessorCheck {
- @Override
- public void check(List<MatcherMailetPair> pairs) throws ConfigurationException {
- Preconditions.checkNotNull(pairs);
- pairs.stream()
- .filter(pair -> pair.getMailet().getClass().equals(VacationMailet.class))
- .filter(pair -> pair.getMatcher().getClass().equals(RecipientIsLocal.class))
- .findAny()
- .orElseThrow(() -> new ConfigurationException("Missing " + VacationMailet.class.getName() + " in mailets configuration (mailetcontainer -> processors -> transport)"));
- }
- }
-
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/8382d619/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
index 0e1af99..72d74f2 100644
--- a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
+++ b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
@@ -44,52 +44,52 @@ public class MailetPreconditionTest {
@Test(expected = ConfigurationException.class)
public void vacationMailetCheckShouldThrowOnEmptyList() throws Exception {
- new JMAPModule.VacationMailetCheck().check(Lists.newArrayList());
+ JMAPModule.VACATION_MAILET_CHECK.check(Lists.newArrayList());
}
@Test(expected = NullPointerException.class)
public void vacationMailetCheckShouldThrowOnNullList() throws Exception {
- new JMAPModule.VacationMailetCheck().check(null);
+ JMAPModule.VACATION_MAILET_CHECK.check(null);
}
@Test(expected = ConfigurationException.class)
public void vacationMailetCheckShouldThrowOnWrongMatcher() throws Exception {
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), new VacationMailet(null, null, null, null, null)));
- new JMAPModule.VacationMailetCheck().check(pairs);
+ JMAPModule.VACATION_MAILET_CHECK.check(pairs);
}
@Test(expected = ConfigurationException.class)
public void vacationMailetCheckShouldThrowOnWrongMailet() throws Exception {
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new Null()));
- new JMAPModule.VacationMailetCheck().check(pairs);
+ JMAPModule.VACATION_MAILET_CHECK.check(pairs);
}
@Test
public void vacationMailetCheckShouldNotThrowIfValidPairPresent() throws Exception {
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new VacationMailet(null, null, null, null, null)));
- new JMAPModule.VacationMailetCheck().check(pairs);
+ JMAPModule.VACATION_MAILET_CHECK.check(pairs);
}
@Test(expected = ConfigurationException.class)
public void bccMailetCheckShouldThrowOnEmptyList() throws Exception {
- new CamelMailetContainerModule.BccMailetCheck().check(Lists.newArrayList());
+ CamelMailetContainerModule.BCC_Check.check(Lists.newArrayList());
}
@Test(expected = NullPointerException.class)
public void bccMailetCheckShouldThrowOnNullList() throws Exception {
- new CamelMailetContainerModule.BccMailetCheck().check(null);
+ CamelMailetContainerModule.BCC_Check.check(null);
}
@Test(expected = ConfigurationException.class)
public void bccMailetCheckShouldThrowOnWrongMatcher() throws Exception {
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new RemoveMimeHeader()));
- new JMAPModule.VacationMailetCheck().check(pairs);
+ JMAPModule.VACATION_MAILET_CHECK.check(pairs);
}
@Test(expected = ConfigurationException.class)
public void bccMailetCheckShouldThrowOnWrongMailet() throws Exception {
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), new Null()));
- new JMAPModule.VacationMailetCheck().check(pairs);
+ JMAPModule.VACATION_MAILET_CHECK.check(pairs);
}
@Test(expected = ConfigurationException.class)
@@ -104,7 +104,7 @@ public class MailetPreconditionTest {
.build());
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), removeMimeHeader));
- new JMAPModule.VacationMailetCheck().check(pairs);
+ JMAPModule.VACATION_MAILET_CHECK.check(pairs);
}
@Test(expected = ConfigurationException.class)
@@ -117,6 +117,6 @@ public class MailetPreconditionTest {
.build());
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), removeMimeHeader));
- new JMAPModule.VacationMailetCheck().check(pairs);
+ JMAPModule.VACATION_MAILET_CHECK.check(pairs);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[15/26] james-project git commit: JAMES-2529 Add tests for
OptionalUtils::ofNullableToStream
Posted by ad...@apache.org.
JAMES-2529 Add tests for OptionalUtils::ofNullableToStream
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/d0ee9686
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/d0ee9686
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/d0ee9686
Branch: refs/heads/master
Commit: d0ee96861c32bfd6ee5ea9ba50919d16f1d97090
Parents: 1e2124e
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 14:53:09 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:03 2018 +0200
----------------------------------------------------------------------
.../apache/james/util/OptionalUtilsTest.java | 23 +++++++++++++-------
1 file changed, 15 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/d0ee9686/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
----------------------------------------------------------------------
diff --git a/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
index 17fe06e..f7d7bf2 100644
--- a/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
@@ -27,8 +27,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import com.github.steveash.guavate.Guavate;
-
public class OptionalUtilsTest {
@Rule
@@ -69,18 +67,14 @@ public class OptionalUtilsTest {
@Test
public void toStreamShouldConvertEmptyOptionalToEmptyStream() {
- assertThat(
- OptionalUtils.toStream(Optional.empty())
- .collect(Guavate.toImmutableList()))
+ assertThat(OptionalUtils.toStream(Optional.empty()))
.isEmpty();
}
@Test
public void toStreamShouldConvertFullOptionalToStream() {
long value = 18L;
- assertThat(
- OptionalUtils.toStream(Optional.of(value))
- .collect(Guavate.toImmutableList()))
+ assertThat(OptionalUtils.toStream(Optional.of(value)))
.containsExactly(value);
}
@@ -91,6 +85,19 @@ public class OptionalUtilsTest {
}
@Test
+ public void ofNullableToStreamShouldReturnAStreamContainingTheValueWhenNotNull() {
+ long value = 18L;
+ assertThat(OptionalUtils.ofNullableToStream(value))
+ .containsExactly(value);
+ }
+
+ @Test
+ public void ofNullableToStreamShouldReturnAnEmptyStreamWhenNull() {
+ assertThat(OptionalUtils.ofNullableToStream(null))
+ .isEmpty();
+ }
+
+ @Test
public void orShouldReturnEmptyWhenEmpty() {
assertThat(
OptionalUtils.or(
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[18/26] james-project git commit: JAMES-2529 Document filtering mailet
Posted by ad...@apache.org.
JAMES-2529 Document filtering mailet
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/472bf31a
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/472bf31a
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/472bf31a
Branch: refs/heads/master
Commit: 472bf31a47f8a5ffaa82a0ba15577eecaab67e96
Parents: b53509c
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Aug 29 12:00:36 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:11:54 2018 +0200
----------------------------------------------------------------------
.../apache/james/jmap/mailet/filter/JMAPFiltering.java | 11 +++++++++++
1 file changed, 11 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/472bf31a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
index a68193a..0a71376 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
@@ -36,6 +36,17 @@ import org.apache.mailet.base.GenericMailet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/**
+ * Mailet for applying JMAP filtering to incoming email.
+ *
+ * Users are able to set their personal filtering rules using JMAP setFilter/getFilter methods.
+ *
+ * Configuring this mailet in the 'transport' processor is mandatory when running a JMAP server.
+ *
+ * Example:
+ *
+ * <mailet matcher="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
+ */
public class JMAPFiltering extends GenericMailet {
private final Logger logger = LoggerFactory.getLogger(JMAPFiltering.class);
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[04/26] james-project git commit: JAMES-2529 Improve addressExtractor
factory method
Posted by ad...@apache.org.
JAMES-2529 Improve addressExtractor factory method
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/016a2826
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/016a2826
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/016a2826
Branch: refs/heads/master
Commit: 016a2826021340c825187ed408d7cce48602a410
Parents: 897cb08
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 09:24:11 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:01 2018 +0200
----------------------------------------------------------------------
.../apache/james/jmap/mailet/filter/MailMatcher.java | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/016a2826/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index c9ea72b..4626a7f 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -21,7 +21,9 @@ package org.apache.james.jmap.mailet.filter;
import static org.apache.james.jmap.api.filtering.Rule.Condition;
+import java.util.Arrays;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
@@ -30,7 +32,6 @@ import javax.mail.Message;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
-import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.james.javax.AddressHelper;
import org.apache.james.jmap.api.filtering.Rule;
@@ -179,9 +180,8 @@ public interface MailMatcher {
.map(Stream::of)
.orElse(Stream.empty());
HeaderExtractor RECIPIENT_EXTRACTOR = mail -> addressExtractor(
- ArrayUtils.addAll(
mail.getMessage().getRecipients(Message.RecipientType.TO),
- mail.getMessage().getRecipients(Message.RecipientType.CC)));
+ mail.getMessage().getRecipients(Message.RecipientType.CC));
HeaderExtractor FROM_EXTRACTOR = mail -> addressExtractor(mail.getMessage().getFrom());
HeaderExtractor CC_EXTRACTOR = recipientExtractor(Message.RecipientType.CC);
@@ -210,10 +210,12 @@ public interface MailMatcher {
return mail -> addressExtractor(mail.getMessage().getRecipients(type));
}
- static Stream<String> addressExtractor(Address[] addresses) {
+ static Stream<String> addressExtractor(Address[]... addresses) {
return Optional.ofNullable(addresses)
- .map(AddressHelper::asStringStream)
- .orElse(Stream.empty());
+ .map(Arrays::stream)
+ .orElse(Stream.empty())
+ .filter(Objects::nonNull)
+ .flatMap(AddressHelper::asStringStream);
}
static Optional<HeaderExtractor> getHeaderExtractor(Field field) {
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[22/26] james-project git commit: JAMES-2529 Modernize default JMAP
configuration
Posted by ad...@apache.org.
JAMES-2529 Modernize default JMAP configuration
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/2dcde783
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/2dcde783
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/2dcde783
Branch: refs/heads/master
Commit: 2dcde783134618cf92690aa697a281606a24d699
Parents: 9ba6a1d
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Aug 29 14:11:00 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:11:55 2018 +0200
----------------------------------------------------------------------
.../resources/defaultJmapMailetContainer.xml | 21 ++++++++------------
1 file changed, 8 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/2dcde783/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml b/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
index 4f70e72..713316e 100644
--- a/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
+++ b/server/container/guice/protocols/jmap/src/main/resources/defaultJmapMailetContainer.xml
@@ -31,8 +31,13 @@
<mailet match="All" class="Null"/>
</processor>
-
<processor state="transport" enableJmx="false">
+ <matcher name="relay-allowed" match="org.apache.james.mailetcontainer.impl.matchers.Or">
+ <matcher match="SMTPAuthSuccessful"/>
+ <matcher match="SMTPIsAuthNetwork"/>
+ <matcher match="SentByMailet"/>
+ <matcher match="org.apache.james.jmap.mailet.SentByJmap"/>
+ </matcher>
<mailet match="SMTPAuthSuccessful" class="SetMimeHeader">
<name>X-UserIsAuth</name>
<value>true</value>
@@ -48,13 +53,7 @@
<processor>local-address-error</processor>
<notice>550 - Requested action not taken: no such user here</notice>
</mailet>
- <mailet match="SMTPAuthSuccessful" class="ToProcessor">
- <processor>relay</processor>
- </mailet>
- <mailet match="org.apache.james.jmap.mailet.SentByJmap" class="ToProcessor">
- <processor>relay</processor>
- </mailet>
- <mailet match="SentByMailet" class="ToProcessor">
+ <mailet match="relay-allowed" class="ToProcessor">
<processor>relay</processor>
</mailet>
<mailet match="All" class="ToProcessor">
@@ -65,7 +64,7 @@
<processor state="relay" enableJmx="true">
<mailet match="All" class="RemoteDelivery">
<outgoingQueue>outgoing</outgoingQueue>
- <delayTime>5000, 100000, 500000</delayTime>
+ <delayTime>5000, 100000, 23*500000</delayTime>
<maxRetries>25</maxRetries>
<maxDnsProblemRetries>0</maxDnsProblemRetries>
<deliveryThreads>10</deliveryThreads>
@@ -74,10 +73,6 @@
</mailet>
</processor>
- <processor state="spam" enableJmx="false">
- <mailet match="All" class="Null"/>
- </processor>
-
<processor state="local-address-error" enableJmx="false">
<mailet match="All" class="Bounce">
<attachment>none</attachment>
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[16/26] james-project git commit: JAMES-2529 Extract ContentMatcher
and HeaderExtractor from MailMatcher
Posted by ad...@apache.org.
JAMES-2529 Extract ContentMatcher and HeaderExtractor from MailMatcher
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/7527daec
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/7527daec
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/7527daec
Branch: refs/heads/master
Commit: 7527daec794b8e0022161e079e9a2bf710c58e77
Parents: aee5424
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 15:02:55 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:03 2018 +0200
----------------------------------------------------------------------
.../jmap/mailet/filter/ContentMatcher.java | 118 +++++++++++++++
.../jmap/mailet/filter/HeaderExtractor.java | 93 ++++++++++++
.../james/jmap/mailet/filter/MailMatcher.java | 150 -------------------
3 files changed, 211 insertions(+), 150 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/7527daec/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
new file mode 100644
index 0000000..a388332
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
@@ -0,0 +1,118 @@
+/****************************************************************
+ * 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.jmap.mailet.filter;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.james.jmap.api.filtering.Rule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableMap;
+
+public interface ContentMatcher {
+
+ class AddressHeader {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AddressHeader.class);
+
+ private final Optional<String> personal;
+ private final Optional<String> address;
+ private final String fullAddress;
+
+ private AddressHeader(String fullAddress) {
+ this.fullAddress = fullAddress;
+ Optional<InternetAddress> internetAddress = parseFullAddress();
+ this.personal = internetAddress.map(InternetAddress::getPersonal);
+ this.address = internetAddress.map(InternetAddress::getAddress);
+ }
+
+ private Optional<InternetAddress> parseFullAddress() {
+ try {
+ return Optional.of(new InternetAddress(fullAddress));
+ } catch (AddressException e) {
+ LOGGER.error("error while parsing full address {}", fullAddress, e);
+ return Optional.empty();
+ }
+ }
+ }
+
+ ContentMatcher STRING_CONTAINS_MATCHER = (contents, valueToMatch) -> contents.anyMatch(content -> StringUtils.contains(content, valueToMatch));
+ ContentMatcher STRING_NOT_CONTAINS_MATCHER = negate(STRING_CONTAINS_MATCHER);
+ ContentMatcher STRING_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents.anyMatch(content -> StringUtils.equals(content, valueToMatch));
+ ContentMatcher STRING_NOT_EXACTLY_EQUALS_MATCHER = negate(STRING_EXACTLY_EQUALS_MATCHER);
+
+ ContentMatcher ADDRESS_CONTAINS_MATCHER = (contents, valueToMatch) -> contents
+ .map(ContentMatcher::asAddressHeader)
+ .anyMatch(addressHeader -> StringUtils.containsIgnoreCase(addressHeader.fullAddress, valueToMatch));
+ ContentMatcher ADDRESS_NOT_CONTAINS_MATCHER = negate(ADDRESS_CONTAINS_MATCHER);
+ ContentMatcher ADDRESS_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents
+ .map(ContentMatcher::asAddressHeader)
+ .anyMatch(addressHeader ->
+ valueToMatch.equalsIgnoreCase(addressHeader.fullAddress)
+ || addressHeader.address.map(valueToMatch::equalsIgnoreCase).orElse(false)
+ || addressHeader.personal.map(valueToMatch::equalsIgnoreCase).orElse(false));
+ ContentMatcher ADDRESS_NOT_EXACTLY_EQUALS_MATCHER = negate(ADDRESS_EXACTLY_EQUALS_MATCHER);
+
+ Map<Rule.Condition.Comparator, ContentMatcher> HEADER_ADDRESS_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
+ .put(Rule.Condition.Comparator.CONTAINS, ADDRESS_CONTAINS_MATCHER)
+ .put(Rule.Condition.Comparator.NOT_CONTAINS, ADDRESS_NOT_CONTAINS_MATCHER)
+ .put(Rule.Condition.Comparator.EXACTLY_EQUALS, ADDRESS_EXACTLY_EQUALS_MATCHER)
+ .put(Rule.Condition.Comparator.NOT_EXACTLY_EQUALS, ADDRESS_NOT_EXACTLY_EQUALS_MATCHER)
+ .build();
+
+ Map<Rule.Condition.Comparator, ContentMatcher> CONTENT_STRING_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
+ .put(Rule.Condition.Comparator.CONTAINS, STRING_CONTAINS_MATCHER)
+ .put(Rule.Condition.Comparator.NOT_CONTAINS, STRING_NOT_CONTAINS_MATCHER)
+ .put(Rule.Condition.Comparator.EXACTLY_EQUALS, STRING_EXACTLY_EQUALS_MATCHER)
+ .put(Rule.Condition.Comparator.NOT_EXACTLY_EQUALS, STRING_NOT_EXACTLY_EQUALS_MATCHER)
+ .build();
+
+ Map<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>> CONTENT_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>>builder()
+ .put(Rule.Condition.Field.SUBJECT, CONTENT_STRING_MATCHER_REGISTRY)
+ .put(Rule.Condition.Field.TO, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .put(Rule.Condition.Field.CC, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .put(Rule.Condition.Field.RECIPIENT, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .put(Rule.Condition.Field.FROM, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .build();
+
+ static ContentMatcher negate(ContentMatcher contentMatcher) {
+ return (Stream<String> contents, String valueToMatch) ->
+ !contentMatcher.match(contents, valueToMatch);
+ }
+
+ static Optional<ContentMatcher> asContentMatcher(Rule.Condition.Field field, Rule.Condition.Comparator comparator) {
+ return Optional
+ .ofNullable(CONTENT_MATCHER_REGISTRY.get(field))
+ .map(matcherRegistry -> matcherRegistry.get(comparator));
+ }
+
+ static AddressHeader asAddressHeader(String addressAsString) {
+ return new AddressHeader(addressAsString);
+ }
+
+ boolean match(Stream<String> contents, String valueToMatch);
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/7527daec/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/HeaderExtractor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/HeaderExtractor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/HeaderExtractor.java
new file mode 100644
index 0000000..65d1629
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/HeaderExtractor.java
@@ -0,0 +1,93 @@
+/****************************************************************
+ * 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.jmap.mailet.filter;
+
+import static org.apache.mailet.base.RFC2822Headers.FROM;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import javax.mail.Address;
+import javax.mail.Message;
+
+import org.apache.james.javax.AddressHelper;
+import org.apache.james.jmap.api.filtering.Rule;
+import org.apache.james.mime4j.util.MimeUtil;
+import org.apache.james.util.StreamUtils;
+import org.apache.mailet.Mail;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.fge.lambdas.functions.ThrowingFunction;
+import com.google.common.collect.ImmutableMap;
+
+public interface HeaderExtractor extends ThrowingFunction<Mail, Stream<String>> {
+ Logger LOGGER = LoggerFactory.getLogger(HeaderExtractor.class);
+
+ HeaderExtractor SUBJECT_EXTRACTOR = mail ->
+ StreamUtils.ofNullables(mail.getMessage().getSubject());
+ HeaderExtractor CC_EXTRACTOR = recipientExtractor(Message.RecipientType.CC);
+ HeaderExtractor TO_EXTRACTOR = recipientExtractor(Message.RecipientType.TO);
+ HeaderExtractor RECIPIENT_EXTRACTOR = and(TO_EXTRACTOR, CC_EXTRACTOR);
+ HeaderExtractor FROM_EXTRACTOR = addressExtractor(mail -> mail.getMessage().getFrom(), FROM);
+
+ Map<Rule.Condition.Field, HeaderExtractor> HEADER_EXTRACTOR_REGISTRY = ImmutableMap.<Rule.Condition.Field, HeaderExtractor>builder()
+ .put(Rule.Condition.Field.SUBJECT, SUBJECT_EXTRACTOR)
+ .put(Rule.Condition.Field.RECIPIENT, RECIPIENT_EXTRACTOR)
+ .put(Rule.Condition.Field.FROM, FROM_EXTRACTOR)
+ .put(Rule.Condition.Field.CC, CC_EXTRACTOR)
+ .put(Rule.Condition.Field.TO, TO_EXTRACTOR)
+ .build();
+
+ static HeaderExtractor and(HeaderExtractor headerExtractor1, HeaderExtractor headerExtractor2) {
+ return (Mail mail) -> StreamUtils.flatten(headerExtractor1.apply(mail), headerExtractor2.apply(mail));
+ }
+
+ static HeaderExtractor recipientExtractor(Message.RecipientType type) {
+ ThrowingFunction<Mail, Address[]> addressGetter = mail -> mail.getMessage().getRecipients(type);
+ String fallbackHeaderName = type.toString();
+
+ return addressExtractor(addressGetter, fallbackHeaderName);
+ }
+
+ static HeaderExtractor addressExtractor(ThrowingFunction<Mail, Address[]> addressGetter, String fallbackHeaderName) {
+ return mail -> {
+ try {
+ return toContent(addressGetter.apply(mail));
+ } catch (Exception e) {
+ LOGGER.info("Failed parsing header. Falling back to unparsed header value matching", e);
+ return Stream.of(mail.getMessage().getHeader(fallbackHeaderName))
+ .map(MimeUtil::unscrambleHeaderValue);
+ }
+ };
+ }
+
+ static Stream<String> toContent(Address[] addresses) {
+ return Optional.ofNullable(addresses)
+ .map(AddressHelper::asStringStream)
+ .orElse(Stream.empty());
+ }
+
+ static Optional<HeaderExtractor> asHeaderExtractor(Rule.Condition.Field field) {
+ return Optional.ofNullable(
+ HeaderExtractor.HEADER_EXTRACTOR_REGISTRY.get(field));
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/7527daec/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index 031e696..ed5db25 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -20,169 +20,19 @@
package org.apache.james.jmap.mailet.filter;
import static org.apache.james.jmap.api.filtering.Rule.Condition;
-import static org.apache.mailet.base.RFC2822Headers.FROM;
-import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
-import javax.mail.Address;
-import javax.mail.Message;
-import javax.mail.internet.AddressException;
-import javax.mail.internet.InternetAddress;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.james.javax.AddressHelper;
import org.apache.james.jmap.api.filtering.Rule;
-import org.apache.james.jmap.api.filtering.Rule.Condition.Field;
-import org.apache.james.mime4j.util.MimeUtil;
-import org.apache.james.util.StreamUtils;
import org.apache.mailet.Mail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.github.fge.lambdas.functions.ThrowingFunction;
import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
public interface MailMatcher {
- interface HeaderExtractor extends ThrowingFunction<Mail, Stream<String>> {
- Logger LOGGER = LoggerFactory.getLogger(HeaderExtractor.class);
-
- HeaderExtractor SUBJECT_EXTRACTOR = mail ->
- StreamUtils.ofNullables(mail.getMessage().getSubject());
- HeaderExtractor CC_EXTRACTOR = recipientExtractor(Message.RecipientType.CC);
- HeaderExtractor TO_EXTRACTOR = recipientExtractor(Message.RecipientType.TO);
- HeaderExtractor RECIPIENT_EXTRACTOR = and(TO_EXTRACTOR, CC_EXTRACTOR);
- HeaderExtractor FROM_EXTRACTOR = addressExtractor(mail -> mail.getMessage().getFrom(), FROM);
-
- Map<Field, HeaderExtractor> HEADER_EXTRACTOR_REGISTRY = ImmutableMap.<Field, HeaderExtractor>builder()
- .put(Field.SUBJECT, SUBJECT_EXTRACTOR)
- .put(Field.RECIPIENT, RECIPIENT_EXTRACTOR)
- .put(Field.FROM, FROM_EXTRACTOR)
- .put(Field.CC, CC_EXTRACTOR)
- .put(Field.TO, TO_EXTRACTOR)
- .build();
-
- static HeaderExtractor and(HeaderExtractor headerExtractor1, HeaderExtractor headerExtractor2) {
- return (Mail mail) -> StreamUtils.flatten(headerExtractor1.apply(mail), headerExtractor2.apply(mail));
- }
-
- static HeaderExtractor recipientExtractor(Message.RecipientType type) {
- ThrowingFunction<Mail, Address[]> addressGetter = mail -> mail.getMessage().getRecipients(type);
- String fallbackHeaderName = type.toString();
-
- return addressExtractor(addressGetter, fallbackHeaderName);
- }
-
- static HeaderExtractor addressExtractor(ThrowingFunction<Mail, Address[]> addressGetter, String fallbackHeaderName) {
- return mail -> {
- try {
- return toContent(addressGetter.apply(mail));
- } catch (Exception e) {
- LOGGER.info("Failed parsing header. Falling back to unparsed header value matching", e);
- return Stream.of(mail.getMessage().getHeader(fallbackHeaderName))
- .map(MimeUtil::unscrambleHeaderValue);
- }
- };
- }
-
- static Stream<String> toContent(Address[] addresses) {
- return Optional.ofNullable(addresses)
- .map(AddressHelper::asStringStream)
- .orElse(Stream.empty());
- }
-
- static Optional<HeaderExtractor> asHeaderExtractor(Field field) {
- return Optional.ofNullable(
- HeaderExtractor.HEADER_EXTRACTOR_REGISTRY.get(field));
- }
- }
-
- interface ContentMatcher {
-
- class AddressHeader {
- private static final Logger LOGGER = LoggerFactory.getLogger(AddressHeader.class);
-
- private final Optional<String> personal;
- private final Optional<String> address;
- private final String fullAddress;
-
- private AddressHeader(String fullAddress) {
- this.fullAddress = fullAddress;
- Optional<InternetAddress> internetAddress = parseFullAddress();
- this.personal = internetAddress.map(InternetAddress::getPersonal);
- this.address = internetAddress.map(InternetAddress::getAddress);
- }
-
- private Optional<InternetAddress> parseFullAddress() {
- try {
- return Optional.of(new InternetAddress(fullAddress));
- } catch (AddressException e) {
- LOGGER.error("error while parsing full address {}", fullAddress, e);
- return Optional.empty();
- }
- }
- }
-
- ContentMatcher STRING_CONTAINS_MATCHER = (contents, valueToMatch) -> contents.anyMatch(content -> StringUtils.contains(content, valueToMatch));
- ContentMatcher STRING_NOT_CONTAINS_MATCHER = negate(STRING_CONTAINS_MATCHER);
- ContentMatcher STRING_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents.anyMatch(content -> StringUtils.equals(content, valueToMatch));
- ContentMatcher STRING_NOT_EXACTLY_EQUALS_MATCHER = negate(STRING_EXACTLY_EQUALS_MATCHER);
-
- ContentMatcher ADDRESS_CONTAINS_MATCHER = (contents, valueToMatch) -> contents
- .map(ContentMatcher::asAddressHeader)
- .anyMatch(addressHeader -> StringUtils.containsIgnoreCase(addressHeader.fullAddress, valueToMatch));
- ContentMatcher ADDRESS_NOT_CONTAINS_MATCHER = negate(ADDRESS_CONTAINS_MATCHER);
- ContentMatcher ADDRESS_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents
- .map(ContentMatcher::asAddressHeader)
- .anyMatch(addressHeader ->
- valueToMatch.equalsIgnoreCase(addressHeader.fullAddress)
- || addressHeader.address.map(valueToMatch::equalsIgnoreCase).orElse(false)
- || addressHeader.personal.map(valueToMatch::equalsIgnoreCase).orElse(false));
- ContentMatcher ADDRESS_NOT_EXACTLY_EQUALS_MATCHER = negate(ADDRESS_EXACTLY_EQUALS_MATCHER);
-
- Map<Rule.Condition.Comparator, ContentMatcher> HEADER_ADDRESS_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
- .put(Condition.Comparator.CONTAINS, ADDRESS_CONTAINS_MATCHER)
- .put(Condition.Comparator.NOT_CONTAINS, ADDRESS_NOT_CONTAINS_MATCHER)
- .put(Condition.Comparator.EXACTLY_EQUALS, ADDRESS_EXACTLY_EQUALS_MATCHER)
- .put(Condition.Comparator.NOT_EXACTLY_EQUALS, ADDRESS_NOT_EXACTLY_EQUALS_MATCHER)
- .build();
-
- Map<Rule.Condition.Comparator, ContentMatcher> CONTENT_STRING_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
- .put(Condition.Comparator.CONTAINS, STRING_CONTAINS_MATCHER)
- .put(Condition.Comparator.NOT_CONTAINS, STRING_NOT_CONTAINS_MATCHER)
- .put(Condition.Comparator.EXACTLY_EQUALS, STRING_EXACTLY_EQUALS_MATCHER)
- .put(Condition.Comparator.NOT_EXACTLY_EQUALS, STRING_NOT_EXACTLY_EQUALS_MATCHER)
- .build();
-
- Map<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>> CONTENT_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>>builder()
- .put(Condition.Field.SUBJECT, CONTENT_STRING_MATCHER_REGISTRY)
- .put(Condition.Field.TO, HEADER_ADDRESS_MATCHER_REGISTRY)
- .put(Condition.Field.CC, HEADER_ADDRESS_MATCHER_REGISTRY)
- .put(Condition.Field.RECIPIENT, HEADER_ADDRESS_MATCHER_REGISTRY)
- .put(Condition.Field.FROM, HEADER_ADDRESS_MATCHER_REGISTRY)
- .build();
-
- static ContentMatcher negate(ContentMatcher contentMatcher) {
- return (Stream<String> contents, String valueToMatch) ->
- !contentMatcher.match(contents, valueToMatch);
- }
-
- static Optional<ContentMatcher> asContentMatcher(Condition.Field field, Condition.Comparator comparator) {
- return Optional
- .ofNullable(CONTENT_MATCHER_REGISTRY.get(field))
- .map(matcherRegistry -> matcherRegistry.get(comparator));
- }
-
- static AddressHeader asAddressHeader(String addressAsString) {
- return new AddressHeader(addressAsString);
- }
-
- boolean match(Stream<String> contents, String valueToMatch);
- }
-
class HeaderMatcher implements MailMatcher {
private static final Logger LOGGER = LoggerFactory.getLogger(HeaderMatcher.class);
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[02/26] james-project git commit: JAMES-2529 Remove final varaiables
Posted by ad...@apache.org.
JAMES-2529 Remove final varaiables
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/e06fb4ac
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/e06fb4ac
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/e06fb4ac
Branch: refs/heads/master
Commit: e06fb4ac82423a0eed9aa31fb3805a5a85d1fb5b
Parents: 59b0e8b
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 10:09:37 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:01 2018 +0200
----------------------------------------------------------------------
.../main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/e06fb4ac/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index d762120..aea0b75 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -199,7 +199,7 @@ public interface MailMatcher {
@Override
public boolean match(Mail mail) {
try {
- final Stream<String> headerLines = headerExtractor.apply(mail);
+ Stream<String> headerLines = headerExtractor.apply(mail);
return contentMatcher.match(headerLines, ruleValue);
} catch (Exception e) {
LOGGER.error("error while extracting mail header", e);
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[26/26] james-project git commit: JAMES-2074 removing
webadmin.properties in webadmin intergation test to avoid confusing
Posted by ad...@apache.org.
JAMES-2074 removing webadmin.properties in webadmin intergation test to avoid confusing
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/072feaca
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/072feaca
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/072feaca
Branch: refs/heads/master
Commit: 072feaca684f640b86ddd59cc5c9cdd8ff1af2a8
Parents: 443f3c6
Author: duc <dt...@linagora.com>
Authored: Thu Aug 30 16:29:51 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:15:34 2018 +0200
----------------------------------------------------------------------
.../src/test/resources/webadmin.properties | 3 ---
1 file changed, 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/072feaca/server/protocols/webadmin-integration-test/src/test/resources/webadmin.properties
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin-integration-test/src/test/resources/webadmin.properties b/server/protocols/webadmin-integration-test/src/test/resources/webadmin.properties
deleted file mode 100644
index 475d655..0000000
--- a/server/protocols/webadmin-integration-test/src/test/resources/webadmin.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-enabled=true
-port=8000
-host=localhost
\ 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
[06/26] james-project git commit: JAMES-2529 Encapsulate MailMatcher
code in relevant sub-classes
Posted by ad...@apache.org.
JAMES-2529 Encapsulate MailMatcher code in relevant sub-classes
This makes reading way easier as in an IDE one can fold complete sub-classes
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/9a2e06d1
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/9a2e06d1
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/9a2e06d1
Branch: refs/heads/master
Commit: 9a2e06d1ace6a54a084ab880ff50416a4dbe2eeb
Parents: 247a851
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 09:36:25 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:01 2018 +0200
----------------------------------------------------------------------
.../james/jmap/mailet/filter/MailMatcher.java | 118 +++++++++----------
1 file changed, 58 insertions(+), 60 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/9a2e06d1/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index d9efaf7..d762120 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -48,36 +48,38 @@ import com.google.common.collect.ImmutableMap;
public interface MailMatcher {
interface HeaderExtractor extends ThrowingFunction<Mail, Stream<String>> {
+ HeaderExtractor SUBJECT_EXTRACTOR = mail ->
+ OptionalUtils.ofNullableToStream(mail.getMessage().getSubject());
+ HeaderExtractor RECIPIENT_EXTRACTOR = mail -> addressExtractor(
+ mail.getMessage().getRecipients(Message.RecipientType.TO),
+ mail.getMessage().getRecipients(Message.RecipientType.CC));
+ HeaderExtractor FROM_EXTRACTOR = mail -> addressExtractor(mail.getMessage().getFrom());
+ HeaderExtractor CC_EXTRACTOR = recipientExtractor(Message.RecipientType.CC);
+ HeaderExtractor TO_EXTRACTOR = recipientExtractor(Message.RecipientType.TO);
+
+ Map<Field, HeaderExtractor> HEADER_EXTRACTOR_REGISTRY = ImmutableMap.<Field, HeaderExtractor>builder()
+ .put(Field.SUBJECT, SUBJECT_EXTRACTOR)
+ .put(Field.RECIPIENT, RECIPIENT_EXTRACTOR)
+ .put(Field.FROM, FROM_EXTRACTOR)
+ .put(Field.CC, CC_EXTRACTOR)
+ .put(Field.TO, TO_EXTRACTOR)
+ .build();
- }
-
- class HeaderMatcher implements MailMatcher {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(HeaderMatcher.class);
-
- private final ContentMatcher contentMatcher;
- private final String ruleValue;
- private final HeaderExtractor headerExtractor;
-
- private HeaderMatcher(ContentMatcher contentMatcher, String ruleValue,
- HeaderExtractor headerExtractor) {
- Preconditions.checkNotNull(contentMatcher);
- Preconditions.checkNotNull(headerExtractor);
+ static HeaderExtractor recipientExtractor(Message.RecipientType type) {
+ return mail -> addressExtractor(mail.getMessage().getRecipients(type));
+ }
- this.contentMatcher = contentMatcher;
- this.ruleValue = ruleValue;
- this.headerExtractor = headerExtractor;
+ static Stream<String> addressExtractor(Address[]... addresses) {
+ return Optional.ofNullable(addresses)
+ .map(Arrays::stream)
+ .orElse(Stream.empty())
+ .filter(Objects::nonNull)
+ .flatMap(AddressHelper::asStringStream);
}
- @Override
- public boolean match(Mail mail) {
- try {
- final Stream<String> headerLines = headerExtractor.apply(mail);
- return contentMatcher.match(headerLines, ruleValue);
- } catch (Exception e) {
- LOGGER.error("error while extracting mail header", e);
- return false;
- }
+ static Optional<HeaderExtractor> asHeaderExtractor(Field field) {
+ return Optional
+ .ofNullable(HeaderExtractor.HEADER_EXTRACTOR_REGISTRY.get(field));
}
}
@@ -176,27 +178,40 @@ public interface MailMatcher {
boolean match(Stream<String> contents, String valueToMatch);
}
- HeaderExtractor SUBJECT_EXTRACTOR = mail ->
- OptionalUtils.ofNullableToStream(mail.getMessage().getSubject());
- HeaderExtractor RECIPIENT_EXTRACTOR = mail -> addressExtractor(
- mail.getMessage().getRecipients(Message.RecipientType.TO),
- mail.getMessage().getRecipients(Message.RecipientType.CC));
- HeaderExtractor FROM_EXTRACTOR = mail -> addressExtractor(mail.getMessage().getFrom());
- HeaderExtractor CC_EXTRACTOR = recipientExtractor(Message.RecipientType.CC);
- HeaderExtractor TO_EXTRACTOR = recipientExtractor(Message.RecipientType.TO);
-
- Map<Field, HeaderExtractor> HEADER_EXTRACTOR_REGISTRY = ImmutableMap.<Field, HeaderExtractor>builder()
- .put(Field.SUBJECT, SUBJECT_EXTRACTOR)
- .put(Field.RECIPIENT, RECIPIENT_EXTRACTOR)
- .put(Field.FROM, FROM_EXTRACTOR)
- .put(Field.CC, CC_EXTRACTOR)
- .put(Field.TO, TO_EXTRACTOR)
- .build();
+ class HeaderMatcher implements MailMatcher {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HeaderMatcher.class);
+
+ private final ContentMatcher contentMatcher;
+ private final String ruleValue;
+ private final HeaderExtractor headerExtractor;
+
+ private HeaderMatcher(ContentMatcher contentMatcher, String ruleValue,
+ HeaderExtractor headerExtractor) {
+ Preconditions.checkNotNull(contentMatcher);
+ Preconditions.checkNotNull(headerExtractor);
+
+ this.contentMatcher = contentMatcher;
+ this.ruleValue = ruleValue;
+ this.headerExtractor = headerExtractor;
+ }
+
+ @Override
+ public boolean match(Mail mail) {
+ try {
+ final Stream<String> headerLines = headerExtractor.apply(mail);
+ return contentMatcher.match(headerLines, ruleValue);
+ } catch (Exception e) {
+ LOGGER.error("error while extracting mail header", e);
+ return false;
+ }
+ }
+ }
static MailMatcher from(Rule rule) {
Condition ruleCondition = rule.getCondition();
Optional<ContentMatcher> maybeContentMatcher = ContentMatcher.asContentMatcher(ruleCondition.getField(), ruleCondition.getComparator());
- Optional<HeaderExtractor> maybeHeaderExtractor = getHeaderExtractor(ruleCondition.getField());
+ Optional<HeaderExtractor> maybeHeaderExtractor = HeaderExtractor.asHeaderExtractor(ruleCondition.getField());
return new HeaderMatcher(
maybeContentMatcher.orElseThrow(() -> new RuntimeException("No content matcher associated with field " + ruleCondition.getField())),
@@ -204,22 +219,5 @@ public interface MailMatcher {
maybeHeaderExtractor.orElseThrow(() -> new RuntimeException("No content matcher associated with comparator " + ruleCondition.getComparator())));
}
- static HeaderExtractor recipientExtractor(Message.RecipientType type) {
- return mail -> addressExtractor(mail.getMessage().getRecipients(type));
- }
-
- static Stream<String> addressExtractor(Address[]... addresses) {
- return Optional.ofNullable(addresses)
- .map(Arrays::stream)
- .orElse(Stream.empty())
- .filter(Objects::nonNull)
- .flatMap(AddressHelper::asStringStream);
- }
-
- static Optional<HeaderExtractor> getHeaderExtractor(Field field) {
- return Optional
- .ofNullable(HEADER_EXTRACTOR_REGISTRY.get(field));
- }
-
boolean match(Mail mail);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[09/26] james-project git commit: JAMES-2529 Falback on address
parsing failure
Posted by ad...@apache.org.
JAMES-2529 Falback on address parsing failure
- (not) exactly-equals default to full header matching
- (not) contains stays fully functional
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/97ba6503
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/97ba6503
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/97ba6503
Branch: refs/heads/master
Commit: 97ba6503c9551d449e6ae3732a61d8b6706d5589
Parents: ee14044
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 11:20:33 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:02 2018 +0200
----------------------------------------------------------------------
.../james/jmap/mailet/filter/MailMatcher.java | 46 +++--
.../jmap/mailet/filter/JMAPFilteringTest.java | 201 +++++++++++++------
2 files changed, 167 insertions(+), 80 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/97ba6503/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index ab7e05d..a7ac517 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -20,10 +20,9 @@
package org.apache.james.jmap.mailet.filter;
import static org.apache.james.jmap.api.filtering.Rule.Condition;
+import static org.apache.mailet.base.RFC2822Headers.FROM;
-import java.util.Arrays;
import java.util.Map;
-import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
@@ -36,7 +35,9 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.james.javax.AddressHelper;
import org.apache.james.jmap.api.filtering.Rule;
import org.apache.james.jmap.api.filtering.Rule.Condition.Field;
+import org.apache.james.mime4j.util.MimeUtil;
import org.apache.james.util.OptionalUtils;
+import org.apache.james.util.StreamUtils;
import org.apache.mailet.Mail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,14 +49,14 @@ import com.google.common.collect.ImmutableMap;
public interface MailMatcher {
interface HeaderExtractor extends ThrowingFunction<Mail, Stream<String>> {
+ Logger LOGGER = LoggerFactory.getLogger(HeaderExtractor.class);
+
HeaderExtractor SUBJECT_EXTRACTOR = mail ->
OptionalUtils.ofNullableToStream(mail.getMessage().getSubject());
- HeaderExtractor RECIPIENT_EXTRACTOR = mail -> addressExtractor(
- mail.getMessage().getRecipients(Message.RecipientType.TO),
- mail.getMessage().getRecipients(Message.RecipientType.CC));
- HeaderExtractor FROM_EXTRACTOR = mail -> addressExtractor(mail.getMessage().getFrom());
HeaderExtractor CC_EXTRACTOR = recipientExtractor(Message.RecipientType.CC);
HeaderExtractor TO_EXTRACTOR = recipientExtractor(Message.RecipientType.TO);
+ HeaderExtractor RECIPIENT_EXTRACTOR = and(TO_EXTRACTOR, CC_EXTRACTOR);
+ HeaderExtractor FROM_EXTRACTOR = addressExtractor(mail -> mail.getMessage().getFrom(), FROM);
Map<Field, HeaderExtractor> HEADER_EXTRACTOR_REGISTRY = ImmutableMap.<Field, HeaderExtractor>builder()
.put(Field.SUBJECT, SUBJECT_EXTRACTOR)
@@ -65,21 +66,38 @@ public interface MailMatcher {
.put(Field.TO, TO_EXTRACTOR)
.build();
+ static HeaderExtractor and(HeaderExtractor headerExtractor1, HeaderExtractor headerExtractor2) {
+ return (Mail mail) -> StreamUtils.flatten(headerExtractor1.apply(mail), headerExtractor2.apply(mail));
+ }
+
static HeaderExtractor recipientExtractor(Message.RecipientType type) {
- return mail -> addressExtractor(mail.getMessage().getRecipients(type));
+ ThrowingFunction<Mail, Address[]> addressGetter = mail -> mail.getMessage().getRecipients(type);
+ String fallbackHeaderName = type.toString();
+
+ return addressExtractor(addressGetter, fallbackHeaderName);
}
- static Stream<String> addressExtractor(Address[]... addresses) {
+ static HeaderExtractor addressExtractor(ThrowingFunction<Mail, Address[]> addressGetter, String fallbackHeaderName) {
+ return mail -> {
+ try {
+ return toContent(addressGetter.apply(mail));
+ } catch (Exception e) {
+ LOGGER.info("Failed parsing header. Falling back to unparsed header value matching", e);
+ return Stream.of(mail.getMessage().getHeader(fallbackHeaderName))
+ .map(MimeUtil::unscrambleHeaderValue);
+ }
+ };
+ }
+
+ static Stream<String> toContent(Address[] addresses) {
return Optional.ofNullable(addresses)
- .map(Arrays::stream)
- .orElse(Stream.empty())
- .filter(Objects::nonNull)
- .flatMap(AddressHelper::asStringStream);
+ .map(AddressHelper::asStringStream)
+ .orElse(Stream.empty());
}
static Optional<HeaderExtractor> asHeaderExtractor(Field field) {
- return Optional
- .ofNullable(HeaderExtractor.HEADER_EXTRACTOR_REGISTRY.get(field));
+ return Optional.ofNullable(
+ HeaderExtractor.HEADER_EXTRACTOR_REGISTRY.get(field));
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/97ba6503/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
index 57bec4a..15ba523 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
@@ -36,7 +36,6 @@ import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.EMPTY;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.FRED_MARTIN_FULLNAME;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.FRED_MARTIN_FULL_SCRAMBLED_ADDRESS;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.GA_BOU_ZO_MEU_FULL_ADDRESS;
-import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1_MAILBOX_1;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.RECIPIENT_1_USERNAME;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.SCRAMBLED_SUBJECT;
@@ -250,45 +249,67 @@ class JMAPFilteringTest {
argumentBuilder(headerField)
.description("folded content (different case)")
.headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
- .valueToMatch(UNFOLDED_USERNAME.toUpperCase())
+ .valueToMatch(UNFOLDED_USERNAME.toUpperCase()),
+ argumentBuilder(headerField)
+ .description("invalid address, personal match")
+ .headerForField("Benoit <invalid>")
+ .valueToMatch("Benoit"),
+ argumentBuilder(headerField)
+ .description("invalid address, address match")
+ .headerForField("Benoit <invalid>")
+ .valueToMatch("invalid"),
+ argumentBuilder(headerField)
+ .description("invalid address, full match")
+ .headerForField("Benoit <invalid>")
+ .valueToMatch("Benoit <invalid>"),
+ argumentBuilder(headerField)
+ .description("invalid header, full match")
+ .headerForField("Benoit <invalid")
+ .valueToMatch("Benoit <invalid")
).map(FilteringArgumentBuilder::build)),
Stream.of(TO_HEADER, CC_HEADER)
.flatMap(headerName -> Stream.of(
- argumentBuilder()
+ argumentBuilder(RECIPIENT)
.description("full address " + headerName + " header")
- .field(RECIPIENT)
.header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(USER_3_FULL_ADDRESS)
- .build(),
- argumentBuilder()
+ .valueToMatch(USER_3_FULL_ADDRESS),
+ argumentBuilder(RECIPIENT)
.description("full address " + headerName + " header (different case)")
- .field(RECIPIENT)
.header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(USER_3_FULL_ADDRESS.toUpperCase(Locale.ENGLISH))
- .build(),
- argumentBuilder()
+ .valueToMatch(USER_3_FULL_ADDRESS.toUpperCase(Locale.ENGLISH)),
+ argumentBuilder(RECIPIENT)
.description("address only " + headerName + " header")
- .field(RECIPIENT).header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(USER_3_ADDRESS)
- .build(),
- argumentBuilder()
+ .header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch(USER_3_ADDRESS),
+ argumentBuilder(RECIPIENT)
.description("personal only " + headerName + " header")
- .field(RECIPIENT)
.header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(USER_3_USERNAME)
- .build(),
- argumentBuilder()
+ .valueToMatch(USER_3_USERNAME),
+ argumentBuilder(RECIPIENT)
.description("scrambled content in " + headerName + " header")
- .field(RECIPIENT)
.header(headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
- .valueToMatch(FRED_MARTIN_FULLNAME)
- .build(),
- argumentBuilder()
+ .valueToMatch(FRED_MARTIN_FULLNAME),
+ argumentBuilder(RECIPIENT)
.description("folded content in " + headerName + " header")
- .field(RECIPIENT)
.header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
- .valueToMatch(UNFOLDED_USERNAME)
- .build())),
+ .valueToMatch(UNFOLDED_USERNAME),
+ argumentBuilder(RECIPIENT)
+ .description("invalid " + headerName + " address, personal match")
+ .header(headerName, "Benoit <invalid>")
+ .valueToMatch("Benoit"),
+ argumentBuilder(RECIPIENT)
+ .description("invalid " + headerName + " address, address match")
+ .header(headerName, "Benoit <invalid>")
+ .valueToMatch("invalid"),
+ argumentBuilder(RECIPIENT)
+ .description("invalid " + headerName + " address, full match")
+ .header(headerName, "Benoit <invalid>")
+ .valueToMatch("Benoit <invalid>"),
+ argumentBuilder(RECIPIENT)
+ .description("invalid " + headerName + ", full match")
+ .header(headerName, "Benoit <invalid")
+ .valueToMatch("Benoit <invalid"))
+ .map(FilteringArgumentBuilder::build)),
Stream.of(
argumentBuilder().description("multiple to and cc headers").field(RECIPIENT)
.ccRecipient(USER_1_FULL_ADDRESS)
@@ -347,46 +368,83 @@ class JMAPFilteringTest {
argumentBuilder(headerField)
.description("folded content (partial matching)")
.headerForField(USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
- .valueToMatch("ded_us"))
+ .valueToMatch("ded_us"),
+ argumentBuilder(headerField)
+ .description("invalid address, personal match (partial matching)")
+ .headerForField("Benoit <invalid>")
+ .valueToMatch("enoi"),
+ argumentBuilder(headerField)
+ .description("invalid address, address match (partial matching)")
+ .headerForField("Benoit <invalid>")
+ .valueToMatch("nvali"),
+ argumentBuilder(headerField)
+ .description("invalid address, full match (partial matching)")
+ .headerForField("Benoit <invalid>")
+ .valueToMatch("enoit <invali"),
+ argumentBuilder(headerField)
+ .description("invalid header, full match (partial matching)")
+ .headerForField("Benoit <invalid")
+ .valueToMatch("enoit <invali"),
+ argumentBuilder(headerField)
+ .description("invalid header, personal match (partial matching)")
+ .headerForField("Benoit <invalid")
+ .valueToMatch("enoi"),
+ argumentBuilder(headerField)
+ .description("invalid header, address match (partial matching)")
+ .headerForField("Benoit <invalid")
+ .valueToMatch("nvali"))
.map(FilteringArgumentBuilder::build)),
Stream.of(TO_HEADER, CC_HEADER)
.flatMap(headerName -> Stream.of(
- argumentBuilder()
+ argumentBuilder(RECIPIENT)
.description("full address " + headerName + " header (partial matching)")
- .field(RECIPIENT)
.header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch("ser3 <us")
- .build(),
- argumentBuilder()
+ .valueToMatch("ser3 <us"),
+ argumentBuilder(RECIPIENT)
.description("full address " + headerName + " header (partial matching, different case)")
- .field(RECIPIENT)
.header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch("SER3 <US")
- .build(),
- argumentBuilder()
+ .valueToMatch("SER3 <US"),
+ argumentBuilder(RECIPIENT)
.description("address only " + headerName + " header (partial matching)")
- .field(RECIPIENT)
.header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch("ser3@jam")
- .build(),
- argumentBuilder()
+ .valueToMatch("ser3@jam"),
+ argumentBuilder(RECIPIENT)
.description("personal only " + headerName + " header (partial matching)")
- .field(RECIPIENT)
.header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch("ser3")
- .build(),
- argumentBuilder()
+ .valueToMatch("ser3"),
+ argumentBuilder(RECIPIENT)
.description("scrambled content in " + headerName + " header (partial matching)")
- .field(RECIPIENT)
.header(headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
- .valueToMatch("déric MAR")
- .build(),
- argumentBuilder()
+ .valueToMatch("déric MAR"),
+ argumentBuilder(RECIPIENT)
.description("folded content in " + headerName + " header (partial matching)")
- .field(RECIPIENT)
.header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
- .valueToMatch("folded_us")
- .build())),
+ .valueToMatch("folded_us"),
+ argumentBuilder(RECIPIENT)
+ .description("invalid address, personal match (partial matching)")
+ .header(headerName, "Benoit <invalid>")
+ .valueToMatch("enoi"),
+ argumentBuilder(RECIPIENT)
+ .description("invalid address, address match (partial matching)")
+ .header(headerName, "Benoit <invalid>")
+ .valueToMatch("nvali"),
+ argumentBuilder(RECIPIENT)
+ .description("invalid address, full match (partial matching)")
+ .header(headerName, "Benoit <invalid>")
+ .valueToMatch("enoit <invali"),
+ argumentBuilder(RECIPIENT)
+ .description("invalid header, full match (partial matching)")
+ .header(headerName, "Benoit <invalid")
+ .valueToMatch("enoit <invali"),
+ argumentBuilder(RECIPIENT)
+ .description("invalid header, personal match (partial matching)")
+ .header(headerName, "Benoit <invalid")
+ .valueToMatch("enoi"),
+ argumentBuilder(RECIPIENT)
+ .description("invalid header, address match (partial matching)")
+ .header(headerName, "Benoit <invalid")
+ .valueToMatch("nvali"))
+ .map(FilteringArgumentBuilder::build)),
Stream.of(
argumentBuilder().description("multiple to and cc headers (partial matching)").field(RECIPIENT)
.ccRecipient(USER_1_FULL_ADDRESS)
@@ -428,32 +486,43 @@ class JMAPFilteringTest {
argumentBuilder(headerField)
.description("empty content")
.headerForField(EMPTY)
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(headerField)
+ .description("invalid address, personal match")
+ .headerForField("Benoit <invalid>")
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(headerField)
+ .description("invalid header, full match")
+ .headerForField("Benoit <invalid")
.valueToMatch(SHOULD_NOT_MATCH))
.map(FilteringArgumentBuilder::build)),
Stream.of(TO_HEADER, CC_HEADER)
.flatMap(headerName -> Stream.of(
- argumentBuilder()
+ argumentBuilder(RECIPIENT)
.description("normal content " + headerName + " header")
- .field(RECIPIENT).header(headerName, USER_3_FULL_ADDRESS)
- .valueToMatch(SHOULD_NOT_MATCH)
- .build(),
- argumentBuilder()
+ .header(headerName, USER_3_FULL_ADDRESS)
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(RECIPIENT)
.description("scrambled content in " + headerName + " header")
.field(RECIPIENT).header(headerName, FRED_MARTIN_FULL_SCRAMBLED_ADDRESS)
- .valueToMatch(SHOULD_NOT_MATCH)
- .build(),
- argumentBuilder()
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(RECIPIENT)
.description("folded content in " + headerName + " header")
- .field(RECIPIENT)
.header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
- .valueToMatch(SHOULD_NOT_MATCH)
- .build(),
- argumentBuilder()
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(RECIPIENT)
.description("bcc header")
- .field(RECIPIENT)
.header(headerName, USER_1_AND_UNFOLDED_USER_FULL_ADDRESS)
- .valueToMatch(SHOULD_NOT_MATCH)
- .build())),
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(RECIPIENT)
+ .description("invalid address, personal match")
+ .header(headerName, "Benoit <invalid>")
+ .valueToMatch(SHOULD_NOT_MATCH),
+ argumentBuilder(RECIPIENT)
+ .description("invalid header, full match")
+ .header(headerName, "Benoit <invalid")
+ .valueToMatch(SHOULD_NOT_MATCH))
+ .map(FilteringArgumentBuilder::build)),
Stream.of(
argumentBuilder().description("multiple to and cc headers").field(RECIPIENT)
.ccRecipient(USER_1_FULL_ADDRESS)
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[07/26] james-project git commit: JAMES-2529 Re-indent MailMatcher
with 4 indent levels
Posted by ad...@apache.org.
JAMES-2529 Re-indent MailMatcher with 4 indent levels
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/247a8516
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/247a8516
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/247a8516
Branch: refs/heads/master
Commit: 247a8516fbec4b129df41a075c97ee9217fbef8e
Parents: 924d23d
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 09:30:15 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:01 2018 +0200
----------------------------------------------------------------------
.../james/jmap/mailet/filter/MailMatcher.java | 77 ++++++++++----------
1 file changed, 38 insertions(+), 39 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/247a8516/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index 185c08b..d9efaf7 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -47,7 +47,9 @@ import com.google.common.collect.ImmutableMap;
public interface MailMatcher {
- interface HeaderExtractor extends ThrowingFunction<Mail, Stream<String>> {}
+ interface HeaderExtractor extends ThrowingFunction<Mail, Stream<String>> {
+
+ }
class HeaderMatcher implements MailMatcher {
@@ -58,7 +60,7 @@ public interface MailMatcher {
private final HeaderExtractor headerExtractor;
private HeaderMatcher(ContentMatcher contentMatcher, String ruleValue,
- HeaderExtractor headerExtractor) {
+ HeaderExtractor headerExtractor) {
Preconditions.checkNotNull(contentMatcher);
Preconditions.checkNotNull(headerExtractor);
@@ -122,45 +124,43 @@ public interface MailMatcher {
ContentMatcher STRING_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents.anyMatch(content -> StringUtils.equals(content, valueToMatch));
ContentMatcher STRING_NOT_EXACTLY_EQUALS_MATCHER = negate(STRING_EXACTLY_EQUALS_MATCHER);
- Map<Rule.Condition.Comparator, ContentMatcher> CONTENT_STRING_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
- .put(Condition.Comparator.CONTAINS, STRING_CONTAINS_MATCHER)
- .put(Condition.Comparator.NOT_CONTAINS, STRING_NOT_CONTAINS_MATCHER)
- .put(Condition.Comparator.EXACTLY_EQUALS, STRING_EXACTLY_EQUALS_MATCHER)
- .put(Condition.Comparator.NOT_EXACTLY_EQUALS, STRING_NOT_EXACTLY_EQUALS_MATCHER)
- .build();
-
ContentMatcher ADDRESS_CONTAINS_MATCHER = (contents, valueToMatch) -> contents
- .map(ContentMatcher::asAddressHeader)
- .anyMatch(addressHeader -> StringUtils.containsIgnoreCase(addressHeader.getFullAddress(), valueToMatch));
-
+ .map(ContentMatcher::asAddressHeader)
+ .anyMatch(addressHeader -> StringUtils.containsIgnoreCase(addressHeader.getFullAddress(), valueToMatch));
ContentMatcher ADDRESS_NOT_CONTAINS_MATCHER = negate(ADDRESS_CONTAINS_MATCHER);
ContentMatcher ADDRESS_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents
- .map(ContentMatcher::asAddressHeader)
- .anyMatch(addressHeader ->
- StringUtils.equalsIgnoreCase(addressHeader.getFullAddress(), valueToMatch)
- || StringUtils.equalsIgnoreCase(addressHeader.getAddress().orElse(null), valueToMatch)
- || StringUtils.equalsIgnoreCase(addressHeader.getPersonal().orElse(null), valueToMatch));
-
+ .map(ContentMatcher::asAddressHeader)
+ .anyMatch(addressHeader ->
+ StringUtils.equalsIgnoreCase(addressHeader.getFullAddress(), valueToMatch)
+ || StringUtils.equalsIgnoreCase(addressHeader.getAddress().orElse(null), valueToMatch)
+ || StringUtils.equalsIgnoreCase(addressHeader.getPersonal().orElse(null), valueToMatch));
ContentMatcher ADDRESS_NOT_EXACTLY_EQUALS_MATCHER = negate(ADDRESS_EXACTLY_EQUALS_MATCHER);
Map<Rule.Condition.Comparator, ContentMatcher> HEADER_ADDRESS_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
- .put(Condition.Comparator.CONTAINS, ADDRESS_CONTAINS_MATCHER)
- .put(Condition.Comparator.NOT_CONTAINS, ADDRESS_NOT_CONTAINS_MATCHER)
- .put(Condition.Comparator.EXACTLY_EQUALS, ADDRESS_EXACTLY_EQUALS_MATCHER)
- .put(Condition.Comparator.NOT_EXACTLY_EQUALS, ADDRESS_NOT_EXACTLY_EQUALS_MATCHER)
- .build();
+ .put(Condition.Comparator.CONTAINS, ADDRESS_CONTAINS_MATCHER)
+ .put(Condition.Comparator.NOT_CONTAINS, ADDRESS_NOT_CONTAINS_MATCHER)
+ .put(Condition.Comparator.EXACTLY_EQUALS, ADDRESS_EXACTLY_EQUALS_MATCHER)
+ .put(Condition.Comparator.NOT_EXACTLY_EQUALS, ADDRESS_NOT_EXACTLY_EQUALS_MATCHER)
+ .build();
+
+ Map<Rule.Condition.Comparator, ContentMatcher> CONTENT_STRING_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
+ .put(Condition.Comparator.CONTAINS, STRING_CONTAINS_MATCHER)
+ .put(Condition.Comparator.NOT_CONTAINS, STRING_NOT_CONTAINS_MATCHER)
+ .put(Condition.Comparator.EXACTLY_EQUALS, STRING_EXACTLY_EQUALS_MATCHER)
+ .put(Condition.Comparator.NOT_EXACTLY_EQUALS, STRING_NOT_EXACTLY_EQUALS_MATCHER)
+ .build();
Map<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>> CONTENT_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>>builder()
- .put(Condition.Field.SUBJECT, CONTENT_STRING_MATCHER_REGISTRY)
- .put(Condition.Field.TO, HEADER_ADDRESS_MATCHER_REGISTRY)
- .put(Condition.Field.CC, HEADER_ADDRESS_MATCHER_REGISTRY)
- .put(Condition.Field.RECIPIENT, HEADER_ADDRESS_MATCHER_REGISTRY)
- .put(Condition.Field.FROM, HEADER_ADDRESS_MATCHER_REGISTRY)
- .build();
+ .put(Condition.Field.SUBJECT, CONTENT_STRING_MATCHER_REGISTRY)
+ .put(Condition.Field.TO, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .put(Condition.Field.CC, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .put(Condition.Field.RECIPIENT, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .put(Condition.Field.FROM, HEADER_ADDRESS_MATCHER_REGISTRY)
+ .build();
static ContentMatcher negate(ContentMatcher contentMatcher) {
return (Stream<String> contents, String valueToMatch) ->
- !contentMatcher.match(contents, valueToMatch);
+ !contentMatcher.match(contents, valueToMatch);
}
static Optional<ContentMatcher> asContentMatcher(Condition.Field field, Condition.Comparator comparator) {
@@ -179,20 +179,19 @@ public interface MailMatcher {
HeaderExtractor SUBJECT_EXTRACTOR = mail ->
OptionalUtils.ofNullableToStream(mail.getMessage().getSubject());
HeaderExtractor RECIPIENT_EXTRACTOR = mail -> addressExtractor(
- mail.getMessage().getRecipients(Message.RecipientType.TO),
- mail.getMessage().getRecipients(Message.RecipientType.CC));
-
+ mail.getMessage().getRecipients(Message.RecipientType.TO),
+ mail.getMessage().getRecipients(Message.RecipientType.CC));
HeaderExtractor FROM_EXTRACTOR = mail -> addressExtractor(mail.getMessage().getFrom());
HeaderExtractor CC_EXTRACTOR = recipientExtractor(Message.RecipientType.CC);
HeaderExtractor TO_EXTRACTOR = recipientExtractor(Message.RecipientType.TO);
Map<Field, HeaderExtractor> HEADER_EXTRACTOR_REGISTRY = ImmutableMap.<Field, HeaderExtractor>builder()
- .put(Field.SUBJECT, SUBJECT_EXTRACTOR)
- .put(Field.RECIPIENT, RECIPIENT_EXTRACTOR)
- .put(Field.FROM, FROM_EXTRACTOR)
- .put(Field.CC, CC_EXTRACTOR)
- .put(Field.TO, TO_EXTRACTOR)
- .build();
+ .put(Field.SUBJECT, SUBJECT_EXTRACTOR)
+ .put(Field.RECIPIENT, RECIPIENT_EXTRACTOR)
+ .put(Field.FROM, FROM_EXTRACTOR)
+ .put(Field.CC, CC_EXTRACTOR)
+ .put(Field.TO, TO_EXTRACTOR)
+ .build();
static MailMatcher from(Rule rule) {
Condition ruleCondition = rule.getCondition();
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[05/26] james-project git commit: JAMES-2529 Apply basic refactoring
to multi-rule testing
Posted by ad...@apache.org.
JAMES-2529 Apply basic refactoring to multi-rule testing
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/59b0e8b0
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/59b0e8b0
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/59b0e8b0
Branch: refs/heads/master
Commit: 59b0e8b0e086dce4ce4999dd9593c22599c4ebd8
Parents: 9a2e06d
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 09:38:05 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:01 2018 +0200
----------------------------------------------------------------------
.../jmap/mailet/filter/JMAPFilteringTest.java | 91 ++++++++------------
1 file changed, 37 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/59b0e8b0/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
index 0d697f8..57bec4a 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
@@ -202,7 +202,7 @@ class JMAPFilteringTest {
return StreamUtils.flatten(
Stream.of(FROM, TO, CC)
.flatMap(headerField -> Stream.of(
- argumentBuilder(headerField)
+ argumentBuilder(headerField)
.description("full address value")
.headerForField(USER_1_FULL_ADDRESS)
.valueToMatch(USER_1_USERNAME),
@@ -614,36 +614,30 @@ class JMAPFilteringTest {
MailboxId mailbox2Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_2");
MailboxId mailbox3Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_3");
- testSystem.defineRulesForRecipient1();
testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
- ImmutableList.of(
- Rule.builder()
- .id(Rule.Id.of("1"))
- .name("rule 1")
- .condition(Rule.Condition.of(SUBJECT, CONTAINS, UNSCRAMBLED_SUBJECT))
- .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(mailbox1Id.serialize())))
- .build(),
- Rule.builder()
- .id(Rule.Id.of("2"))
- .name("rule 2")
- .condition(Rule.Condition.of(FROM, NOT_CONTAINS, USER_1_USERNAME))
- .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(mailbox2Id.serialize())))
- .build(),
- Rule.builder()
- .id(Rule.Id.of("3"))
- .name("rule 3")
- .condition(Rule.Condition.of(TO, EXACTLY_EQUALS, USER_3_ADDRESS))
- .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(mailbox3Id.serialize())))
- .build()));
-
- FakeMail mail = FakeMail.builder()
- .sender(USER_1_ADDRESS)
- .recipients(RECIPIENT_1)
- .mimeMessage(mimeMessageBuilder()
+ Rule.builder()
+ .id(Rule.Id.of("1"))
+ .name("rule 1")
+ .condition(Rule.Condition.of(SUBJECT, CONTAINS, UNSCRAMBLED_SUBJECT))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(mailbox1Id.serialize())))
+ .build(),
+ Rule.builder()
+ .id(Rule.Id.of("2"))
+ .name("rule 2")
+ .condition(Rule.Condition.of(FROM, NOT_CONTAINS, USER_1_USERNAME))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(mailbox2Id.serialize())))
+ .build(),
+ Rule.builder()
+ .id(Rule.Id.of("3"))
+ .name("rule 3")
+ .condition(Rule.Condition.of(TO, EXACTLY_EQUALS, USER_3_ADDRESS))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(mailbox3Id.serialize())))
+ .build());
+
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder()
.addFrom(USER_2_ADDRESS)
.addToRecipient(USER_3_ADDRESS)
- .setSubject(UNSCRAMBLED_SUBJECT))
- .build();
+ .setSubject(UNSCRAMBLED_SUBJECT));
testSystem.getJmapFiltering().service(mail);
@@ -659,23 +653,18 @@ class JMAPFilteringTest {
MailboxId mailbox3Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_3");
testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
- ImmutableList.of(
- Rule.builder()
- .id(Rule.Id.of("1"))
- .name("rule 1")
- .condition(Rule.Condition.of(SUBJECT, CONTAINS, UNSCRAMBLED_SUBJECT))
- .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(ImmutableList.of(
- mailbox3Id.serialize(),
- mailbox2Id.serialize(),
- mailbox1Id.serialize()))))
- .build()));
-
- FakeMail mail = FakeMail.builder()
- .sender(USER_1_ADDRESS)
- .recipients(RECIPIENT_1)
- .mimeMessage(mimeMessageBuilder()
- .setSubject(UNSCRAMBLED_SUBJECT))
- .build();
+ Rule.builder()
+ .id(Rule.Id.of("1"))
+ .name("rule 1")
+ .condition(Rule.Condition.of(SUBJECT, CONTAINS, UNSCRAMBLED_SUBJECT))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(ImmutableList.of(
+ mailbox3Id.serialize(),
+ mailbox2Id.serialize(),
+ mailbox1Id.serialize()))))
+ .build());
+
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder()
+ .setSubject(UNSCRAMBLED_SUBJECT));
testSystem.getJmapFiltering().service(mail);
@@ -695,8 +684,7 @@ class JMAPFilteringTest {
Rule.Condition.of(RECIPIENT, EXACTLY_EQUALS, USER_1_FULL_ADDRESS),
Rule.Condition.of(RECIPIENT, EXACTLY_EQUALS, USER_1_FULL_ADDRESS),
Rule.Condition.of(SUBJECT, CONTAINS, USER_1_FULL_ADDRESS),
- Rule.Condition.of(SUBJECT, EXACTLY_EQUALS, USER_1_FULL_ADDRESS)
- );
+ Rule.Condition.of(SUBJECT, EXACTLY_EQUALS, USER_1_FULL_ADDRESS));
FakeMail mail = testSystem.asMail(mimeMessageBuilder());
testSystem.getJmapFiltering().service(mail);
@@ -707,20 +695,15 @@ class JMAPFilteringTest {
@Test
void mailDirectiveShouldNotBeSetWhenNoneRulesValueIsContained(JMAPFilteringTestSystem testSystem) throws Exception {
-
testSystem.defineRulesForRecipient1(
Rule.Condition.of(FROM, CONTAINS, SHOULD_NOT_MATCH),
Rule.Condition.of(TO, CONTAINS, SHOULD_NOT_MATCH),
Rule.Condition.of(CC, CONTAINS, SHOULD_NOT_MATCH));
- FakeMail mail = FakeMail.builder()
- .sender(USER_1_ADDRESS)
- .recipients(RECIPIENT_1)
- .mimeMessage(mimeMessageBuilder()
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder()
.addFrom(USER_1_FULL_ADDRESS)
.addToRecipient(USER_2_FULL_ADDRESS)
- .addCcRecipient(USER_3_FULL_ADDRESS))
- .build();
+ .addCcRecipient(USER_3_FULL_ADDRESS));
testSystem.getJmapFiltering().service(mail);
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[10/26] james-project git commit: JAMES-2529 Remove getter for
AddressHeader
Posted by ad...@apache.org.
JAMES-2529 Remove getter for AddressHeader
The code is only used by the MailMatcher class thus this boiler plate code is not required.
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ee14044c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ee14044c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ee14044c
Branch: refs/heads/master
Commit: ee14044c842916b0f36e1d09b2199cb971a936ce
Parents: b62bc55
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 10:23:48 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:02 2018 +0200
----------------------------------------------------------------------
.../james/jmap/mailet/filter/MailMatcher.java | 20 ++++----------------
1 file changed, 4 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/ee14044c/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index 410146e..ab7e05d 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -107,18 +107,6 @@ public interface MailMatcher {
return Optional.empty();
}
}
-
- public Optional<String> getPersonal() {
- return personal;
- }
-
- public Optional<String> getAddress() {
- return address;
- }
-
- public String getFullAddress() {
- return fullAddress;
- }
}
ContentMatcher STRING_CONTAINS_MATCHER = (contents, valueToMatch) -> contents.anyMatch(content -> StringUtils.contains(content, valueToMatch));
@@ -128,14 +116,14 @@ public interface MailMatcher {
ContentMatcher ADDRESS_CONTAINS_MATCHER = (contents, valueToMatch) -> contents
.map(ContentMatcher::asAddressHeader)
- .anyMatch(addressHeader -> StringUtils.containsIgnoreCase(addressHeader.getFullAddress(), valueToMatch));
+ .anyMatch(addressHeader -> StringUtils.containsIgnoreCase(addressHeader.fullAddress, valueToMatch));
ContentMatcher ADDRESS_NOT_CONTAINS_MATCHER = negate(ADDRESS_CONTAINS_MATCHER);
ContentMatcher ADDRESS_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> contents
.map(ContentMatcher::asAddressHeader)
.anyMatch(addressHeader ->
- valueToMatch.equalsIgnoreCase(addressHeader.getFullAddress())
- || addressHeader.getAddress().map(valueToMatch::equalsIgnoreCase).orElse(false)
- || addressHeader.getPersonal().map(valueToMatch::equalsIgnoreCase).orElse(false));
+ valueToMatch.equalsIgnoreCase(addressHeader.fullAddress)
+ || addressHeader.address.map(valueToMatch::equalsIgnoreCase).orElse(false)
+ || addressHeader.personal.map(valueToMatch::equalsIgnoreCase).orElse(false));
ContentMatcher ADDRESS_NOT_EXACTLY_EQUALS_MATCHER = negate(ADDRESS_EXACTLY_EQUALS_MATCHER);
Map<Rule.Condition.Comparator, ContentMatcher> HEADER_ADDRESS_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, ContentMatcher>builder()
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[08/26] james-project git commit: JAMES-2529 ActionApplier should
handle MailboxNotFound
Posted by ad...@apache.org.
JAMES-2529 ActionApplier should handle MailboxNotFound
This case can happen frequently. Example:
- Bob create the 'toto' mailbox
- Bob set up a rule to redirect mails from Fred to the 'toto' mailbox
- Bob deletes the 'toto' mailbox
- Fred sends a mail to Bob
Note that this is implemented by applying all actions (and thus relaxing the 'first applied' tests)
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/8b1c70ab
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/8b1c70ab
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/8b1c70ab
Branch: refs/heads/master
Commit: 8b1c70aba0032173c21ed377820eba4932c811fb
Parents: 97ba650
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 11:33:40 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:02 2018 +0200
----------------------------------------------------------------------
.../james/jmap/mailet/filter/ActionApplier.java | 33 +++--
.../james/jmap/mailet/filter/JMAPFiltering.java | 9 +-
.../james/jmap/mailet/filter/RuleMatcher.java | 7 +-
.../mailet/filter/JMAPFilteringExtension.java | 4 +-
.../jmap/mailet/filter/JMAPFilteringTest.java | 143 +++++++++++++++++--
5 files changed, 160 insertions(+), 36 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1c70ab/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
index fdb55ac..7006801 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
@@ -19,6 +19,8 @@
package org.apache.james.jmap.mailet.filter;
+import java.util.stream.Stream;
+
import javax.inject.Inject;
import org.apache.james.core.User;
@@ -27,14 +29,18 @@ import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageManager;
import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.mailet.Mail;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.github.fge.lambdas.Throwing;
import com.google.common.annotations.VisibleForTesting;
public class ActionApplier {
static final String DELIVERY_PATH_PREFIX = "DeliveryPath_";
+ public static final Logger LOGGER = LoggerFactory.getLogger(ActionApplier.class);
@VisibleForTesting
static class Factory {
@@ -81,21 +87,22 @@ public class ActionApplier {
this.user = user;
}
- public void apply(Rule.Action action) {
- action.getAppendInMailboxes()
- .getMailboxIds()
- .stream()
- .findFirst()
- .map(mailboxIdFactory::fromString)
- .ifPresent(Throwing.consumer(this::addStorageDirective));
+ public void apply(Stream<Rule.Action> actions) {
+ actions.flatMap(action -> action.getAppendInMailboxes().getMailboxIds().stream())
+ .map(mailboxIdFactory::fromString)
+ .forEach(Throwing.consumer(this::addStorageDirective));
}
private void addStorageDirective(MailboxId mailboxId) throws MailboxException {
- MailboxSession mailboxSession = mailboxManager.createSystemSession(user.asString());
- MessageManager messageManager = mailboxManager.getMailbox(mailboxId, mailboxSession);
-
- String mailboxName = messageManager.getMailboxPath().getName();
- String attributeNameForUser = DELIVERY_PATH_PREFIX + user.asString();
- mail.setAttribute(attributeNameForUser, mailboxName);
+ try {
+ MailboxSession mailboxSession = mailboxManager.createSystemSession(user.asString());
+ MessageManager messageManager = mailboxManager.getMailbox(mailboxId, mailboxSession);
+
+ String mailboxName = messageManager.getMailboxPath().getName();
+ String attributeNameForUser = DELIVERY_PATH_PREFIX + user.asString();
+ mail.setAttribute(attributeNameForUser, mailboxName);
+ } catch (MailboxNotFoundException e) {
+ LOGGER.info("Mailbox {} does not exist, but it was mentioned in a JMAP filtering rule", mailboxId, e);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1c70ab/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
index 388fabe..a68193a 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
@@ -21,6 +21,7 @@ package org.apache.james.jmap.mailet.filter;
import java.util.List;
import java.util.Optional;
+import java.util.stream.Stream;
import javax.inject.Inject;
@@ -67,11 +68,11 @@ public class JMAPFiltering extends GenericMailet {
private void findFirstApplicableRule(User user, Mail mail) {
List<Rule> filteringRules = filteringManagement.listRulesForUser(user);
RuleMatcher ruleMatcher = new RuleMatcher(filteringRules);
- Optional<Rule> maybeMatchingRule = ruleMatcher.findApplicableRule(mail);
+ Stream<Rule> matchingRules = ruleMatcher.findApplicableRules(mail);
- maybeMatchingRule.ifPresent(rule -> actionApplierFactory.forMail(mail)
- .forUser(user)
- .apply(rule.getAction()));
+ actionApplierFactory.forMail(mail)
+ .forUser(user)
+ .apply(matchingRules.map(Rule::getAction));
}
private Optional<User> retrieveUser(MailAddress recipient) {
http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1c70ab/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/RuleMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/RuleMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/RuleMatcher.java
index abc1da1..07f0371 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/RuleMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/RuleMatcher.java
@@ -20,7 +20,7 @@
package org.apache.james.jmap.mailet.filter;
import java.util.List;
-import java.util.Optional;
+import java.util.stream.Stream;
import org.apache.james.jmap.api.filtering.Rule;
import org.apache.mailet.Mail;
@@ -36,9 +36,8 @@ class RuleMatcher {
this.filteringRules = filteringRules;
}
- Optional<Rule> findApplicableRule(Mail mail) {
+ Stream<Rule> findApplicableRules(Mail mail) {
return filteringRules.stream()
- .filter(rule -> MailMatcher.from(rule).match(mail))
- .findFirst();
+ .filter(rule -> MailMatcher.from(rule).match(mail));
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1c70ab/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringExtension.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringExtension.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringExtension.java
index 05dc317..526c94b 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringExtension.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringExtension.java
@@ -68,7 +68,7 @@ public class JMAPFilteringExtension implements BeforeEachCallback, ParameterReso
this.filteringManagement = filteringManagement;
this.mailboxManager = mailboxManager;
try {
- this.recipient1Mailbox = createMailbox(mailboxManager, RECIPIENT_1_USERNAME, RECIPIENT_1_MAILBOX_1);
+ this.recipient1Mailbox = createMailbox(RECIPIENT_1_USERNAME, RECIPIENT_1_MAILBOX_1);
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -90,7 +90,7 @@ public class JMAPFilteringExtension implements BeforeEachCallback, ParameterReso
return recipient1Mailbox;
}
- public MailboxId createMailbox(InMemoryMailboxManager mailboxManager, String username, String mailboxName) throws Exception {
+ public MailboxId createMailbox(String username, String mailboxName) throws Exception {
MailboxSession mailboxSession = mailboxManager.createSystemSession(username);
return mailboxManager
.createMailbox(MailboxPath.forUser(username, mailboxName), mailboxSession)
http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1c70ab/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
index 15ba523..29d6bca 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/filter/JMAPFilteringTest.java
@@ -54,6 +54,7 @@ import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_3_FU
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_3_USERNAME;
import static org.apache.james.jmap.mailet.filter.JMAPFilteringFixture.USER_4_FULL_ADDRESS;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
import java.util.Locale;
import java.util.Optional;
@@ -63,7 +64,6 @@ import org.apache.james.core.User;
import org.apache.james.core.builder.MimeMessageBuilder;
import org.apache.james.jmap.api.filtering.Rule;
import org.apache.james.jmap.mailet.filter.JMAPFilteringExtension.JMAPFilteringTestSystem;
-import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.util.StreamUtils;
import org.apache.mailet.base.test.FakeMail;
@@ -677,11 +677,10 @@ class JMAPFilteringTest {
@Nested
class MultiRuleBehaviourTest {
@Test
- void mailDirectiveShouldSetFirstMatchedRuleWhenMultipleRules(JMAPFilteringTestSystem testSystem) throws Exception {
- InMemoryMailboxManager mailboxManager = testSystem.getMailboxManager();
- MailboxId mailbox1Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_1");
- MailboxId mailbox2Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_2");
- MailboxId mailbox3Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_3");
+ void mailDirectiveShouldSetLastMatchedRuleWhenMultipleRules(JMAPFilteringTestSystem testSystem) throws Exception {
+ MailboxId mailbox1Id = testSystem.createMailbox(RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_1");
+ MailboxId mailbox2Id = testSystem.createMailbox(RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_2");
+ MailboxId mailbox3Id = testSystem.createMailbox(RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_3");
testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
Rule.builder()
@@ -711,15 +710,14 @@ class JMAPFilteringTest {
testSystem.getJmapFiltering().service(mail);
assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
- .isEqualTo("RECIPIENT_1_MAILBOX_1");
+ .isEqualTo("RECIPIENT_1_MAILBOX_3");
}
@Test
- void mailDirectiveShouldSetFirstMatchedMailboxWhenMultipleMailboxes(JMAPFilteringTestSystem testSystem) throws Exception {
- InMemoryMailboxManager mailboxManager = testSystem.getMailboxManager();
- MailboxId mailbox1Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_1");
- MailboxId mailbox2Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_2");
- MailboxId mailbox3Id = testSystem.createMailbox(mailboxManager, RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_3");
+ void mailDirectiveShouldSetLastMatchedMailboxWhenMultipleMailboxes(JMAPFilteringTestSystem testSystem) throws Exception {
+ MailboxId mailbox1Id = testSystem.createMailbox(RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_1");
+ MailboxId mailbox2Id = testSystem.createMailbox(RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_2");
+ MailboxId mailbox3Id = testSystem.createMailbox(RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_3");
testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
Rule.builder()
@@ -738,7 +736,35 @@ class JMAPFilteringTest {
testSystem.getJmapFiltering().service(mail);
assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
- .isEqualTo("RECIPIENT_1_MAILBOX_3");
+ .isEqualTo("RECIPIENT_1_MAILBOX_1");
+ }
+
+ @Test
+ void rulesWithEmptyMailboxIdsShouldBeSkept(JMAPFilteringTestSystem testSystem) throws Exception {
+ MailboxId mailbox1Id = testSystem.createMailbox(RECIPIENT_1_USERNAME, "RECIPIENT_1_MAILBOX_1");
+
+ testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
+ Rule.builder()
+ .id(Rule.Id.of("1"))
+ .name("rule 1")
+ .condition(Rule.Condition.of(SUBJECT, CONTAINS, UNSCRAMBLED_SUBJECT))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(ImmutableList.of())))
+ .build(),
+ Rule.builder()
+ .id(Rule.Id.of("2"))
+ .name("rule 2")
+ .condition(Rule.Condition.of(SUBJECT, CONTAINS, UNSCRAMBLED_SUBJECT))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(ImmutableList.of(
+ mailbox1Id.serialize()))))
+ .build());
+
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder()
+ .setSubject(UNSCRAMBLED_SUBJECT));
+
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isEqualTo("RECIPIENT_1_MAILBOX_1");
}
@Test
@@ -780,4 +806,95 @@ class JMAPFilteringTest {
.isNull();
}
}
+
+ @Nested
+ class UnknownMailboxIds {
+ @Test
+ void serviceShouldNotThrowWhenUnknownMailboxId(JMAPFilteringTestSystem testSystem) throws Exception {
+ String unknownMailboxId = "4242";
+ testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
+ Rule.builder()
+ .id(Rule.Id.of("1"))
+ .name("rule 1")
+ .condition(Rule.Condition.of(FROM, CONTAINS, FRED_MARTIN_FULLNAME))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(unknownMailboxId)))
+ .build());
+
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder()
+ .addFrom(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS));
+
+ assertThatCode(() -> testSystem.getJmapFiltering().service(mail))
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ void mailDirectiveShouldNotBeSetWhenUnknownMailboxId(JMAPFilteringTestSystem testSystem) throws Exception {
+ String unknownMailboxId = "4242";
+ testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
+ Rule.builder()
+ .id(Rule.Id.of("1"))
+ .name("rule 1")
+ .condition(Rule.Condition.of(FROM, CONTAINS, FRED_MARTIN_FULLNAME))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(unknownMailboxId)))
+ .build());
+
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder()
+ .addFrom(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS));
+
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isNull();
+ }
+
+ @Test
+ void rulesWithInvalidMailboxIdsShouldBeSkept(JMAPFilteringTestSystem testSystem) throws Exception {
+ String unknownMailboxId = "4242";
+ testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
+ Rule.builder()
+ .id(Rule.Id.of("1"))
+ .name("rule 1")
+ .condition(Rule.Condition.of(FROM, CONTAINS, FRED_MARTIN_FULLNAME))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(unknownMailboxId)))
+ .build(),
+ Rule.builder()
+ .id(Rule.Id.of("2"))
+ .name("rule 2")
+ .condition(Rule.Condition.of(FROM, CONTAINS, FRED_MARTIN_FULLNAME))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(
+ testSystem.getRecipient1MailboxId().serialize())))
+ .build());
+
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder()
+ .addFrom(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS));
+
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isEqualTo(RECIPIENT_1_MAILBOX_1);
+ }
+
+ @Test
+ void rulesWithMultipleMailboxIdsShouldFallbackWhenInvalidFirstMailboxId(JMAPFilteringTestSystem testSystem) throws Exception {
+ String unknownMailboxId = "4242";
+
+ testSystem.getFilteringManagement().defineRulesForUser(User.fromUsername(RECIPIENT_1_USERNAME),
+ Rule.builder()
+ .id(Rule.Id.of("1"))
+ .name("rule 1")
+ .condition(Rule.Condition.of(FROM, CONTAINS, FRED_MARTIN_FULLNAME))
+ .action(Rule.Action.of(Rule.Action.AppendInMailboxes.withMailboxIds(
+ unknownMailboxId,
+ testSystem.getRecipient1MailboxId().serialize())))
+ .build());
+
+ FakeMail mail = testSystem.asMail(mimeMessageBuilder()
+ .addFrom(FRED_MARTIN_FULL_SCRAMBLED_ADDRESS));
+
+ testSystem.getJmapFiltering().service(mail);
+
+ assertThat(mail.getAttribute(DELIVERY_PATH_PREFIX + RECIPIENT_1_USERNAME))
+ .isEqualTo(RECIPIENT_1_MAILBOX_1);
+ }
+ }
}
\ 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
[21/26] james-project git commit: JAMES-2529 Correct
MailetPreconditionTest for BCC_CHECK
Posted by ad...@apache.org.
JAMES-2529 Correct MailetPreconditionTest for BCC_CHECK
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a8a8a905
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a8a8a905
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a8a8a905
Branch: refs/heads/master
Commit: a8a8a905a63423ae48f48c1a15e5501ca874c4ba
Parents: 8382d61
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Aug 29 12:23:48 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:11:55 2018 +0200
----------------------------------------------------------------------
.../james/jmap/MailetPreconditionTest.java | 32 +++++++++-----------
1 file changed, 14 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/a8a8a905/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
index 72d74f2..04832d6 100644
--- a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
+++ b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
@@ -20,7 +20,6 @@
package org.apache.james.jmap;
import java.util.List;
-import java.util.Properties;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.james.jmap.mailet.VacationMailet;
@@ -39,7 +38,6 @@ import com.google.common.collect.Lists;
public class MailetPreconditionTest {
private static final MailetContext MAILET_CONTEXT = null;
- private static final String WRONG_NAME = "wrong";
private static final String BCC = "bcc";
@Test(expected = ConfigurationException.class)
@@ -83,40 +81,38 @@ public class MailetPreconditionTest {
@Test(expected = ConfigurationException.class)
public void bccMailetCheckShouldThrowOnWrongMatcher() throws Exception {
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new RemoveMimeHeader()));
- JMAPModule.VACATION_MAILET_CHECK.check(pairs);
+ CamelMailetContainerModule.BCC_Check.check(pairs);
}
@Test(expected = ConfigurationException.class)
public void bccMailetCheckShouldThrowOnWrongMailet() throws Exception {
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), new Null()));
- JMAPModule.VACATION_MAILET_CHECK.check(pairs);
+ CamelMailetContainerModule.BCC_Check.check(pairs);
}
@Test(expected = ConfigurationException.class)
- public void bccMailetCheckShouldThrowOnWrongMailetName() throws Exception {
- Properties properties = new Properties();
- properties.setProperty("name", WRONG_NAME);
+ public void bccMailetCheckShouldThrowOnWrongFieldName() throws Exception {
RemoveMimeHeader removeMimeHeader = new RemoveMimeHeader();
removeMimeHeader.init(FakeMailetConfig.builder()
- .mailetName(WRONG_NAME)
- .mailetContext(MAILET_CONTEXT)
- .setProperty("name", WRONG_NAME)
- .build());
+ .mailetName(BCC)
+ .mailetContext(MAILET_CONTEXT)
+ .setProperty("name", "bad")
+ .build());
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), removeMimeHeader));
- JMAPModule.VACATION_MAILET_CHECK.check(pairs);
+ CamelMailetContainerModule.BCC_Check.check(pairs);
}
- @Test(expected = ConfigurationException.class)
+ @Test
public void bccMailetCheckShouldNotThrowOnValidPair() throws Exception {
RemoveMimeHeader removeMimeHeader = new RemoveMimeHeader();
removeMimeHeader.init(FakeMailetConfig.builder()
- .mailetName(BCC)
- .mailetContext(MAILET_CONTEXT)
- .setProperty("name", BCC)
- .build());
+ .mailetName(BCC)
+ .mailetContext(MAILET_CONTEXT)
+ .setProperty("name", BCC)
+ .build());
List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), removeMimeHeader));
- JMAPModule.VACATION_MAILET_CHECK.check(pairs);
+ CamelMailetContainerModule.BCC_Check.check(pairs);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[14/26] james-project git commit: JAMES-2529 Replace
OptionalUtils::ofNullableToStream by StreamUtils::ofNullables
Posted by ad...@apache.org.
JAMES-2529 Replace OptionalUtils::ofNullableToStream by StreamUtils::ofNullables
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/aee5424b
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/aee5424b
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/aee5424b
Branch: refs/heads/master
Commit: aee5424b30de411ab0e6cf467d63cf49bc4959ae
Parents: d0ee968
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 14:57:19 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:03 2018 +0200
----------------------------------------------------------------------
.../main/java/org/apache/james/util/OptionalUtils.java | 4 ----
.../main/java/org/apache/james/util/StreamUtils.java | 4 ++++
.../java/org/apache/james/util/OptionalUtilsTest.java | 13 -------------
.../james/transport/matchers/dlp/DlpDomainRules.java | 3 ++-
.../apache/james/jmap/mailet/filter/MailMatcher.java | 3 +--
5 files changed, 7 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/aee5424b/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java
----------------------------------------------------------------------
diff --git a/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java b/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java
index 8f64e38..4a3449c 100644
--- a/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java
+++ b/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java
@@ -42,10 +42,6 @@ public class OptionalUtils {
.orElse(Stream.of());
}
- public static <T> Stream<T> ofNullableToStream(T maybeNull) {
- return toStream(Optional.ofNullable(maybeNull));
- }
-
@SafeVarargs
public static <T> Optional<T> or(Optional<T>... optionals) {
return orStream(Arrays.stream(optionals));
http://git-wip-us.apache.org/repos/asf/james-project/blob/aee5424b/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java
----------------------------------------------------------------------
diff --git a/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java b/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java
index e8a71bd..4f3df3f 100644
--- a/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java
+++ b/server/container/util/src/main/java/org/apache/james/util/StreamUtils.java
@@ -27,6 +27,10 @@ import java.util.stream.Stream;
public class StreamUtils {
+ public static <T> Stream<T> ofNullables(T... array) {
+ return ofNullable(array);
+ }
+
public static <T> Stream<T> ofNullable(T[] array) {
return ofOptional(Optional.ofNullable(array));
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/aee5424b/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
----------------------------------------------------------------------
diff --git a/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
index f7d7bf2..c0cf551 100644
--- a/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/OptionalUtilsTest.java
@@ -85,19 +85,6 @@ public class OptionalUtilsTest {
}
@Test
- public void ofNullableToStreamShouldReturnAStreamContainingTheValueWhenNotNull() {
- long value = 18L;
- assertThat(OptionalUtils.ofNullableToStream(value))
- .containsExactly(value);
- }
-
- @Test
- public void ofNullableToStreamShouldReturnAnEmptyStreamWhenNull() {
- assertThat(OptionalUtils.ofNullableToStream(null))
- .isEmpty();
- }
-
- @Test
public void orShouldReturnEmptyWhenEmpty() {
assertThat(
OptionalUtils.or(
http://git-wip-us.apache.org/repos/asf/james-project/blob/aee5424b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
index 3dcfec7..b954801 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
@@ -39,6 +39,7 @@ import org.apache.james.dlp.api.DLPConfigurationItem.Targets;
import org.apache.james.javax.AddressHelper;
import org.apache.james.javax.MultipartUtil;
import org.apache.james.util.OptionalUtils;
+import org.apache.james.util.StreamUtils;
import org.apache.mailet.Mail;
import com.github.fge.lambdas.Throwing;
@@ -168,7 +169,7 @@ public class DlpDomainRules {
}
private Stream<String> listEnvelopSender(Mail mail) {
- return OptionalUtils.ofNullableToStream(mail.getSender()).map(MailAddress::asString);
+ return StreamUtils.ofNullables(mail.getSender()).map(MailAddress::asString);
}
private Stream<String> listFromHeaders(Mail mail) throws MessagingException {
http://git-wip-us.apache.org/repos/asf/james-project/blob/aee5424b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index a7ac517..031e696 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -36,7 +36,6 @@ import org.apache.james.javax.AddressHelper;
import org.apache.james.jmap.api.filtering.Rule;
import org.apache.james.jmap.api.filtering.Rule.Condition.Field;
import org.apache.james.mime4j.util.MimeUtil;
-import org.apache.james.util.OptionalUtils;
import org.apache.james.util.StreamUtils;
import org.apache.mailet.Mail;
import org.slf4j.Logger;
@@ -52,7 +51,7 @@ public interface MailMatcher {
Logger LOGGER = LoggerFactory.getLogger(HeaderExtractor.class);
HeaderExtractor SUBJECT_EXTRACTOR = mail ->
- OptionalUtils.ofNullableToStream(mail.getMessage().getSubject());
+ StreamUtils.ofNullables(mail.getMessage().getSubject());
HeaderExtractor CC_EXTRACTOR = recipientExtractor(Message.RecipientType.CC);
HeaderExtractor TO_EXTRACTOR = recipientExtractor(Message.RecipientType.TO);
HeaderExtractor RECIPIENT_EXTRACTOR = and(TO_EXTRACTOR, CC_EXTRACTOR);
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[20/26] james-project git commit: JAMES-2529 Rewrite
MailetPreconditionTest with JUNIT 5
Posted by ad...@apache.org.
JAMES-2529 Rewrite MailetPreconditionTest with JUNIT 5
Use nested classes to enhance readability
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/7164031c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/7164031c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/7164031c
Branch: refs/heads/master
Commit: 7164031c3226c4bf8313335ffd7800683f7a0b30
Parents: a8a8a90
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Aug 29 12:32:28 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:11:55 2018 +0200
----------------------------------------------------------------------
server/container/guice/protocols/jmap/pom.xml | 18 +-
.../james/jmap/MailetPreconditionTest.java | 175 +++++++++++--------
2 files changed, 115 insertions(+), 78 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/7164031c/server/container/guice/protocols/jmap/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/pom.xml b/server/container/guice/protocols/jmap/pom.xml
index 9cce57a..df48b58 100644
--- a/server/container/guice/protocols/jmap/pom.xml
+++ b/server/container/guice/protocols/jmap/pom.xml
@@ -71,13 +71,23 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.assertj</groupId>
- <artifactId>assertj-core</artifactId>
+ <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>
</dependencies>
http://git-wip-us.apache.org/repos/asf/james-project/blob/7164031c/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
index 04832d6..aaacbd9 100644
--- a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
+++ b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/jmap/MailetPreconditionTest.java
@@ -19,6 +19,9 @@
package org.apache.james.jmap;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
import java.util.List;
import org.apache.commons.configuration.ConfigurationException;
@@ -31,88 +34,112 @@ import org.apache.james.transport.matchers.All;
import org.apache.james.transport.matchers.RecipientIsLocal;
import org.apache.mailet.MailetContext;
import org.apache.mailet.base.test.FakeMailetConfig;
-import org.junit.Test;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
import com.google.common.collect.Lists;
-public class MailetPreconditionTest {
+class MailetPreconditionTest {
private static final MailetContext MAILET_CONTEXT = null;
private static final String BCC = "bcc";
- @Test(expected = ConfigurationException.class)
- public void vacationMailetCheckShouldThrowOnEmptyList() throws Exception {
- JMAPModule.VACATION_MAILET_CHECK.check(Lists.newArrayList());
- }
-
- @Test(expected = NullPointerException.class)
- public void vacationMailetCheckShouldThrowOnNullList() throws Exception {
- JMAPModule.VACATION_MAILET_CHECK.check(null);
- }
-
- @Test(expected = ConfigurationException.class)
- public void vacationMailetCheckShouldThrowOnWrongMatcher() throws Exception {
- List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), new VacationMailet(null, null, null, null, null)));
- JMAPModule.VACATION_MAILET_CHECK.check(pairs);
- }
-
- @Test(expected = ConfigurationException.class)
- public void vacationMailetCheckShouldThrowOnWrongMailet() throws Exception {
- List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new Null()));
- JMAPModule.VACATION_MAILET_CHECK.check(pairs);
- }
-
- @Test
- public void vacationMailetCheckShouldNotThrowIfValidPairPresent() throws Exception {
- List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new VacationMailet(null, null, null, null, null)));
- JMAPModule.VACATION_MAILET_CHECK.check(pairs);
- }
-
- @Test(expected = ConfigurationException.class)
- public void bccMailetCheckShouldThrowOnEmptyList() throws Exception {
- CamelMailetContainerModule.BCC_Check.check(Lists.newArrayList());
- }
-
- @Test(expected = NullPointerException.class)
- public void bccMailetCheckShouldThrowOnNullList() throws Exception {
- CamelMailetContainerModule.BCC_Check.check(null);
- }
-
- @Test(expected = ConfigurationException.class)
- public void bccMailetCheckShouldThrowOnWrongMatcher() throws Exception {
- List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new RemoveMimeHeader()));
- CamelMailetContainerModule.BCC_Check.check(pairs);
- }
-
- @Test(expected = ConfigurationException.class)
- public void bccMailetCheckShouldThrowOnWrongMailet() throws Exception {
- List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), new Null()));
- CamelMailetContainerModule.BCC_Check.check(pairs);
- }
-
- @Test(expected = ConfigurationException.class)
- public void bccMailetCheckShouldThrowOnWrongFieldName() throws Exception {
- RemoveMimeHeader removeMimeHeader = new RemoveMimeHeader();
- removeMimeHeader.init(FakeMailetConfig.builder()
- .mailetName(BCC)
- .mailetContext(MAILET_CONTEXT)
- .setProperty("name", "bad")
- .build());
-
- List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), removeMimeHeader));
- CamelMailetContainerModule.BCC_Check.check(pairs);
+ @Nested
+ class VacationMailetCheck {
+ @Test
+ void vacationMailetCheckShouldThrowOnEmptyList() {
+ assertThatThrownBy(() -> JMAPModule.VACATION_MAILET_CHECK.check(Lists.newArrayList()))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void vacationMailetCheckShouldThrowOnNullList() {
+ assertThatThrownBy(() -> JMAPModule.VACATION_MAILET_CHECK.check(null))
+ .isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ void vacationMailetCheckShouldThrowOnWrongMatcher() {
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), new VacationMailet(null, null, null, null, null)));
+
+ assertThatThrownBy(() -> JMAPModule.VACATION_MAILET_CHECK.check(pairs))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void vacationMailetCheckShouldThrowOnWrongMailet() {
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new Null()));
+
+ assertThatThrownBy(() -> JMAPModule.VACATION_MAILET_CHECK.check(pairs))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void vacationMailetCheckShouldNotThrowIfValidPairPresent() {
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new VacationMailet(null, null, null, null, null)));
+
+ assertThatCode(() -> JMAPModule.VACATION_MAILET_CHECK.check(pairs))
+ .doesNotThrowAnyException();
+ }
}
- @Test
- public void bccMailetCheckShouldNotThrowOnValidPair() throws Exception {
- RemoveMimeHeader removeMimeHeader = new RemoveMimeHeader();
- removeMimeHeader.init(FakeMailetConfig.builder()
- .mailetName(BCC)
- .mailetContext(MAILET_CONTEXT)
- .setProperty("name", BCC)
- .build());
-
- List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), removeMimeHeader));
- CamelMailetContainerModule.BCC_Check.check(pairs);
+ @Nested
+ class BccCheck {
+ @Test
+ void bccMailetCheckShouldThrowOnEmptyList() {
+ assertThatThrownBy(() -> CamelMailetContainerModule.BCC_Check.check(Lists.newArrayList()))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void bccMailetCheckShouldThrowOnNullList() {
+ assertThatThrownBy(() -> CamelMailetContainerModule.BCC_Check.check(null))
+ .isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ void bccMailetCheckShouldThrowOnWrongMatcher() {
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new RecipientIsLocal(), new RemoveMimeHeader()));
+
+ assertThatThrownBy(() -> CamelMailetContainerModule.BCC_Check.check(pairs))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void bccMailetCheckShouldThrowOnWrongMailet() {
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), new Null()));
+
+ assertThatThrownBy(() -> CamelMailetContainerModule.BCC_Check.check(pairs))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void bccMailetCheckShouldThrowOnWrongFieldName() throws Exception {
+ RemoveMimeHeader removeMimeHeader = new RemoveMimeHeader();
+ removeMimeHeader.init(FakeMailetConfig.builder()
+ .mailetName(BCC)
+ .mailetContext(MAILET_CONTEXT)
+ .setProperty("name", "bad")
+ .build());
+
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), removeMimeHeader));
+
+ assertThatThrownBy(() -> CamelMailetContainerModule.BCC_Check.check(pairs))
+ .isInstanceOf(ConfigurationException.class);
+ }
+
+ @Test
+ void bccMailetCheckShouldNotThrowOnValidPair() throws Exception {
+ RemoveMimeHeader removeMimeHeader = new RemoveMimeHeader();
+ removeMimeHeader.init(FakeMailetConfig.builder()
+ .mailetName(BCC)
+ .mailetContext(MAILET_CONTEXT)
+ .setProperty("name", BCC)
+ .build());
+
+ List<MatcherMailetPair> pairs = Lists.newArrayList(new MatcherMailetPair(new All(), removeMimeHeader));
+ assertThatCode(() -> CamelMailetContainerModule.BCC_Check.check(pairs))
+ .doesNotThrowAnyException();
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[23/26] james-project git commit: JAMES-2529 Filter case sensitivity
integration test
Posted by ad...@apache.org.
JAMES-2529 Filter case sensitivity integration test
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/443f3c61
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/443f3c61
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/443f3c61
Branch: refs/heads/master
Commit: 443f3c612ae2f63513f0c63b3e914bff05df0f07
Parents: 2dcde78
Author: Raphael Ouazana <ra...@linagora.com>
Authored: Wed Aug 29 17:31:35 2018 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:11:55 2018 +0200
----------------------------------------------------------------------
.../jmap/methods/integration/FilterTest.java | 113 +++++++++++++++++++
1 file changed, 113 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/443f3c61/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
index f56615c..e87c417 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
@@ -41,6 +41,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
import java.io.IOException;
+import java.util.Locale;
import org.apache.james.GuiceJamesServer;
import org.apache.james.jmap.JmapCommonRequests;
@@ -1219,6 +1220,62 @@ public abstract class FilterTest {
() -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
}
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenSubjectRuleDoesNotMatchRuleBecaseOfCase() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"subject\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"different case value\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"},{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + "\"}]," +
+ " \"subject\": \"DIFFERENT CASE VALUE\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
@Test
public void messageShouldBeAppendedInSpecificMailboxWhenContainsComparatorMatches() {
given()
@@ -1494,6 +1551,62 @@ public abstract class FilterTest {
() -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
}
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenExactlyEqualsMatchesCaseInsensitivelyFullHeader() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"exactly-equals\"," +
+ " \"value\": \"bob <" + BOB.toUpperCase(Locale.ENGLISH) + ">\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
@Test
public void messageShouldBeAppendedInInboxWhenExactlyEqualsComparatorDoesNotMatch() {
given()
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[12/26] james-project git commit: JAMES-2529 Handling all mailbox
exceptions while resolving mailbox name
Posted by ad...@apache.org.
JAMES-2529 Handling all mailbox exceptions while resolving mailbox name
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/1e2124e0
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/1e2124e0
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/1e2124e0
Branch: refs/heads/master
Commit: 1e2124e0ee253bbfb6942740546e6422996dfdfe
Parents: c6a6e97
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 14:01:10 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:03 2018 +0200
----------------------------------------------------------------------
.../org/apache/james/jmap/mailet/filter/ActionApplier.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/1e2124e0/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
index 7006801..72376ab 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
@@ -28,14 +28,12 @@ import org.apache.james.jmap.api.filtering.Rule;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.MailboxNotFoundException;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.mailet.Mail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.github.fge.lambdas.Throwing;
import com.google.common.annotations.VisibleForTesting;
public class ActionApplier {
@@ -90,10 +88,10 @@ public class ActionApplier {
public void apply(Stream<Rule.Action> actions) {
actions.flatMap(action -> action.getAppendInMailboxes().getMailboxIds().stream())
.map(mailboxIdFactory::fromString)
- .forEach(Throwing.consumer(this::addStorageDirective));
+ .forEach(this::addStorageDirective);
}
- private void addStorageDirective(MailboxId mailboxId) throws MailboxException {
+ private void addStorageDirective(MailboxId mailboxId) {
try {
MailboxSession mailboxSession = mailboxManager.createSystemSession(user.asString());
MessageManager messageManager = mailboxManager.getMailbox(mailboxId, mailboxSession);
@@ -103,6 +101,8 @@ public class ActionApplier {
mail.setAttribute(attributeNameForUser, mailboxName);
} catch (MailboxNotFoundException e) {
LOGGER.info("Mailbox {} does not exist, but it was mentioned in a JMAP filtering rule", mailboxId, e);
+ } catch (Exception e) {
+ LOGGER.error("Unexpected failure while resolving mailbox name for {}", mailboxId, e);
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[03/26] james-project git commit: JAMES-2529 Add a
OptionalUtils::ofNullableToStream convenience method
Posted by ad...@apache.org.
JAMES-2529 Add a OptionalUtils::ofNullableToStream convenience method
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/924d23df
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/924d23df
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/924d23df
Branch: refs/heads/master
Commit: 924d23df354ebcb76b835a5916d93ac33d64111e
Parents: 016a282
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Aug 30 09:28:07 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:07:01 2018 +0200
----------------------------------------------------------------------
.../util/src/main/java/org/apache/james/util/OptionalUtils.java | 4 ++++
.../org/apache/james/transport/matchers/dlp/DlpDomainRules.java | 2 +-
.../java/org/apache/james/jmap/mailet/filter/MailMatcher.java | 5 ++---
3 files changed, 7 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/924d23df/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java
----------------------------------------------------------------------
diff --git a/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java b/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java
index 4a3449c..8f64e38 100644
--- a/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java
+++ b/server/container/util/src/main/java/org/apache/james/util/OptionalUtils.java
@@ -42,6 +42,10 @@ public class OptionalUtils {
.orElse(Stream.of());
}
+ public static <T> Stream<T> ofNullableToStream(T maybeNull) {
+ return toStream(Optional.ofNullable(maybeNull));
+ }
+
@SafeVarargs
public static <T> Optional<T> or(Optional<T>... optionals) {
return orStream(Arrays.stream(optionals));
http://git-wip-us.apache.org/repos/asf/james-project/blob/924d23df/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
index d3f0eef..3dcfec7 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/DlpDomainRules.java
@@ -168,7 +168,7 @@ public class DlpDomainRules {
}
private Stream<String> listEnvelopSender(Mail mail) {
- return OptionalUtils.toStream(Optional.ofNullable(mail.getSender()).map(MailAddress::asString));
+ return OptionalUtils.ofNullableToStream(mail.getSender()).map(MailAddress::asString);
}
private Stream<String> listFromHeaders(Mail mail) throws MessagingException {
http://git-wip-us.apache.org/repos/asf/james-project/blob/924d23df/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
index 4626a7f..185c08b 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/filter/MailMatcher.java
@@ -36,6 +36,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.james.javax.AddressHelper;
import org.apache.james.jmap.api.filtering.Rule;
import org.apache.james.jmap.api.filtering.Rule.Condition.Field;
+import org.apache.james.util.OptionalUtils;
import org.apache.mailet.Mail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -176,9 +177,7 @@ public interface MailMatcher {
}
HeaderExtractor SUBJECT_EXTRACTOR = mail ->
- Optional.ofNullable(mail.getMessage().getSubject())
- .map(Stream::of)
- .orElse(Stream.empty());
+ OptionalUtils.ofNullableToStream(mail.getMessage().getSubject());
HeaderExtractor RECIPIENT_EXTRACTOR = mail -> addressExtractor(
mail.getMessage().getRecipients(Message.RecipientType.TO),
mail.getMessage().getRecipients(Message.RecipientType.CC));
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[17/26] james-project git commit: JAMES-2529 Integration tests for
JMAP filtering on incoming mails
Posted by ad...@apache.org.
JAMES-2529 Integration tests for JMAP filtering on incoming mails
Exercise all fields and a basic subset of comparators.
More fine grained testing is done in unit tests.
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b53509c2
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b53509c2
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b53509c2
Branch: refs/heads/master
Commit: b53509c2ced5710305b5302270ced65ad5f5d1ee
Parents: 7527dae
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Aug 29 11:52:09 2018 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Aug 30 15:11:54 2018 +0200
----------------------------------------------------------------------
.../src/test/resources/mailetcontainer.xml | 1 +
.../apache/james/jmap/JmapCommonRequests.java | 19 +
.../jmap/methods/integration/FilterTest.java | 1572 +++++++++++++++++-
.../src/test/resources/mailetcontainer.xml | 3 +-
4 files changed, 1582 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/b53509c2/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
index 887c947..2ecff3f 100644
--- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
+++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
@@ -72,6 +72,7 @@
<mailet match="IsMarkedAsSpam" class="WithStorageDirective">
<targetFolderName>Spam</targetFolderName>
</mailet>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
<mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
http://git-wip-us.apache.org/repos/asf/james-project/blob/b53509c2/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java
index ef61472..fe3f84d 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java
@@ -32,6 +32,7 @@ import java.util.Map;
import org.apache.james.jmap.api.access.AccessToken;
import org.apache.james.mailbox.Role;
+import org.apache.james.mailbox.model.MailboxId;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.specification.ResponseSpecification;
@@ -85,6 +86,24 @@ public class JmapCommonRequests {
}
}
+ public static boolean isAnyMessageFoundInRecipientsMailbox(AccessToken recipientToken, MailboxId mailboxId) {
+ try {
+ with()
+ .header("Authorization", recipientToken.serialize())
+ .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + mailboxId.serialize() + "\"]}}, \"#0\"]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200)
+ .body(NAME, equalTo("messageList"))
+ .body(ARGUMENTS + ".messageIds", hasSize(1));
+ return true;
+
+ } catch (AssertionError e) {
+ return false;
+ }
+ }
+
public static String getInboxId(AccessToken accessToken) {
return getMailboxId(accessToken, Role.INBOX);
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/b53509c2/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
index 643c844..f56615c 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
@@ -22,13 +22,20 @@ package org.apache.james.jmap.methods.integration;
import static io.restassured.RestAssured.given;
import static io.restassured.RestAssured.with;
import static org.apache.james.jmap.HttpJmapAuthentication.authenticateJamesUser;
+import static org.apache.james.jmap.JmapCommonRequests.getOutboxId;
import static org.apache.james.jmap.JmapURIBuilder.baseUri;
import static org.apache.james.jmap.TestingConstants.ALICE;
import static org.apache.james.jmap.TestingConstants.ALICE_PASSWORD;
import static org.apache.james.jmap.TestingConstants.ARGUMENTS;
+import static org.apache.james.jmap.TestingConstants.BOB;
+import static org.apache.james.jmap.TestingConstants.BOB_PASSWORD;
+import static org.apache.james.jmap.TestingConstants.CEDRIC;
import static org.apache.james.jmap.TestingConstants.DOMAIN;
import static org.apache.james.jmap.TestingConstants.NAME;
+import static org.apache.james.jmap.TestingConstants.calmlyAwait;
import static org.apache.james.jmap.TestingConstants.jmapRequestSpecBuilder;
+import static org.apache.james.mailbox.model.MailboxConstants.INBOX;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
@@ -36,8 +43,11 @@ import static org.hamcrest.Matchers.hasSize;
import java.io.IOException;
import org.apache.james.GuiceJamesServer;
+import org.apache.james.jmap.JmapCommonRequests;
import org.apache.james.jmap.api.access.AccessToken;
import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.modules.MailboxProbeImpl;
import org.apache.james.probe.DataProbe;
import org.apache.james.utils.DataProbeImpl;
import org.apache.james.utils.JmapGuiceProbe;
@@ -54,21 +64,31 @@ public abstract class FilterTest {
protected abstract MailboxId randomMailboxId();
private AccessToken accessToken;
+ private AccessToken bobAccessToken;
private GuiceJamesServer jmapServer;
+ private MailboxId matchedMailbox;
+ private MailboxId inbox;
+
@Before
public void setup() throws Throwable {
jmapServer = createJmapServer();
jmapServer.start();
RestAssured.requestSpecification = jmapRequestSpecBuilder
- .setPort(jmapServer.getProbe(JmapGuiceProbe.class).getJmapPort())
- .build();
+ .setPort(jmapServer.getProbe(JmapGuiceProbe.class).getJmapPort())
+ .build();
DataProbe dataProbe = jmapServer.getProbe(DataProbeImpl.class);
dataProbe.addDomain(DOMAIN);
dataProbe.addUser(ALICE, ALICE_PASSWORD);
+ dataProbe.addUser(BOB, BOB_PASSWORD);
accessToken = authenticateJamesUser(baseUri(jmapServer), ALICE, ALICE_PASSWORD);
+ bobAccessToken = authenticateJamesUser(baseUri(jmapServer), BOB, BOB_PASSWORD);
+
+ MailboxProbeImpl mailboxProbe = jmapServer.getProbe(MailboxProbeImpl.class);
+ matchedMailbox = mailboxProbe.createMailbox(MailboxPath.forUser(ALICE, "matched"));
+ inbox = mailboxProbe.createMailbox(MailboxPath.forUser(ALICE, INBOX));
}
@After
@@ -100,7 +120,7 @@ public abstract class FilterTest {
MailboxId mailbox1 = randomMailboxId();
MailboxId mailbox2 = randomMailboxId();
- with()
+ given()
.header("Authorization", accessToken.serialize())
.body("[[" +
" \"setFilter\", " +
@@ -123,7 +143,11 @@ public abstract class FilterTest {
" ]}, " +
"\"#0\"" +
"]]")
- .post("/jmap");
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
with()
.header("Authorization", accessToken.serialize())
.body("[[" +
@@ -147,7 +171,10 @@ public abstract class FilterTest {
" ]}, " +
"\"#0\"" +
"]]")
- .post("/jmap");
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
given()
.header("Authorization", accessToken.serialize())
@@ -336,7 +363,7 @@ public abstract class FilterTest {
MailboxId mailbox1 = randomMailboxId();
MailboxId mailbox2 = randomMailboxId();
- with()
+ given()
.header("Authorization", accessToken.serialize())
.body("[[" +
" \"setFilter\", " +
@@ -373,7 +400,10 @@ public abstract class FilterTest {
" ]}, " +
"\"#0\"" +
"]]")
- .post("/jmap");
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
given()
.header("Authorization", accessToken.serialize())
@@ -406,7 +436,7 @@ public abstract class FilterTest {
public void setFilterShouldClearPreviouslyStoredRulesWhenEmptyBody() {
MailboxId mailbox = randomMailboxId();
- with()
+ given()
.header("Authorization", accessToken.serialize())
.body("[[" +
" \"setFilter\", " +
@@ -429,7 +459,10 @@ public abstract class FilterTest {
" ]}, " +
"\"#0\"" +
"]]")
- .post("/jmap");
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
with()
.header("Authorization", accessToken.serialize())
@@ -440,7 +473,10 @@ public abstract class FilterTest {
" }, " +
"\"#0\"" +
"]]")
- .post("/jmap");
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
given()
.header("Authorization", accessToken.serialize())
@@ -461,7 +497,7 @@ public abstract class FilterTest {
public void allFieldsAndComparatorsShouldBeSupported() {
MailboxId mailbox = randomMailboxId();
- with()
+ given()
.header("Authorization", accessToken.serialize())
.body("[[" +
" \"setFilter\", " +
@@ -540,7 +576,10 @@ public abstract class FilterTest {
" ]}, " +
"\"#0\"" +
"]]")
- .post("/jmap");
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
given()
.header("Authorization", accessToken.serialize())
@@ -572,4 +611,1513 @@ public abstract class FilterTest {
.body(ARGUMENTS + ".singleton[4].condition.comparator", equalTo("contains"));
}
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenFromRuleMatches() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + BOB + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap");
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenToRuleMatches() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails to cedric\"," +
+ " \"condition\": {" +
+ " \"field\": \"to\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + CEDRIC + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"},{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenCcRuleMatches() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails cc-ed to cedric\"," +
+ " \"condition\": {" +
+ " \"field\": \"cc\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + CEDRIC + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenRecipientRuleMatchesCc() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails cc-ed to cedric\"," +
+ " \"condition\": {" +
+ " \"field\": \"recipient\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + CEDRIC + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenRecipientRuleMatchesTo() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails cc-ed to cedric\"," +
+ " \"condition\": {" +
+ " \"field\": \"recipient\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + CEDRIC + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + CEDRIC + "\"}]," +
+ " \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenSubjectRuleMatches() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"subject\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"matchme\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"},{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + "\"}]," +
+ " \"subject\": \"matchme\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenFromDoesNotMatchRule() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + CEDRIC + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenToDoesNotMatchRule() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails to cedric\"," +
+ " \"condition\": {" +
+ " \"field\": \"to\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + CEDRIC + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenCcDoesNotMatchRule() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails cc-ed to cedric\"," +
+ " \"condition\": {" +
+ " \"field\": \"cc\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + CEDRIC + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + BOB + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenRecipientDoesNotMatchRule() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails cc-ed to cedric\"," +
+ " \"condition\": {" +
+ " \"field\": \"recipient\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + CEDRIC + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + BOB + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenSubjectRuleDoesNotMatchRule() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"subject\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"matchme\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"},{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + "\"}]," +
+ " \"subject\": \"nomatch\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenContainsComparatorMatches() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"bo\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenContainsComparatorDoesNotMatch() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"ced\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenExactlyEqualsMatchesName() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"exactly-equals\"," +
+ " \"value\": \"Bob\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenExactlyEqualsMatchesAddress() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"exactly-equals\"," +
+ " \"value\": \"" + BOB + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenExactlyEqualsMatchesFullHeader() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"exactly-equals\"," +
+ " \"value\": \"Bob <" + BOB + ">\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenExactlyEqualsComparatorDoesNotMatch() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"exactly-equals\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"nomatch\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenNotContainsComparatorMatches() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"not-contains\"," +
+ " \"value\": \"other\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenNotContainsComparatorDoesNotMatch() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"not-contains\"," +
+ " \"value\": \"bob\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenContainsNotExactlyEqualsMatches() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"not-exactly-equals\"," +
+ " \"value\": \"nomatch\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenNotExactlyEqualsMatchesAddress() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"not-exactly-equals\"," +
+ " \"value\": \"" + BOB + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenNotExactlyEqualsMatchesFullHeader() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"not-exactly-equals\"," +
+ " \"value\": \"Bob <" + BOB + ">\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInInboxWhenNotExactlyEqualsComparatorMatchesName() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"not-exactly-equals\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"Bob\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenFirstRuleMatches() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + BOB + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }," +
+ " {" +
+ " \"id\": \"3000-346\"," +
+ " \"name\": \"Emails to alice\"," +
+ " \"condition\": {" +
+ " \"field\": \"to\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + ALICE + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap");
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void messageShouldBeAppendedInSpecificMailboxWhenSecondRuleMatches() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"unknown@james.org\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }," +
+ " {" +
+ " \"id\": \"3000-346\"," +
+ " \"name\": \"Emails to alice\"," +
+ " \"condition\": {" +
+ " \"field\": \"to\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + ALICE + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap");
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ }
+
+ @Test
+ public void inboxShouldBeEmptyWhenFromRuleMatchesInSpecificMailbox() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"" + BOB + "\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap");
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox));
+ assertThat(JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox)).isFalse();
+ }
+
+ @Test
+ public void matchedMailboxShouldBeEmptyWhenFromRuleDoesntMatch() {
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body("[[" +
+ " \"setFilter\", " +
+ " {" +
+ " \"singleton\": [" +
+ " {" +
+ " \"id\": \"3000-345\"," +
+ " \"name\": \"Emails from bob\"," +
+ " \"condition\": {" +
+ " \"field\": \"from\"," +
+ " \"comparator\": \"contains\"," +
+ " \"value\": \"unknown@james.org\"" +
+ " }," +
+ " \"action\": {" +
+ " \"appendIn\": {" +
+ " \"mailboxIds\": [\"" + matchedMailbox.serialize() + "\"]" +
+ " }" +
+ " }" +
+ " }" +
+ " ]}, " +
+ "\"#0\"" +
+ "]]")
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200);
+
+ String messageCreationId = "creationId1337";
+ String requestBody = "[[" +
+ " \"setMessages\"," +
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," +
+ " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ "]]";
+
+ with()
+ .header("Authorization", bobAccessToken.serialize())
+ .body(requestBody)
+ .post("/jmap");
+
+ calmlyAwait.until(
+ () -> JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+ assertThat(JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, matchedMailbox)).isFalse();
+ }
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/b53509c2/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml
index c783fd3..c890709 100644
--- a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml
+++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml
@@ -73,7 +73,8 @@
<mailet match="IsMarkedAsSpam" class="WithStorageDirective">
<targetFolderName>Spam</targetFolderName>
</mailet>
- <mailet match="RecipientIsLocal" class="LocalDelivery"/>
+ <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
+ <mailet match="RecipientIsLocal" class="LocalDelivery"/>
<mailet match="HostIsLocal" class="ToProcessor">
<processor>local-address-error</processor>
<notice>550 - Requested action not taken: no such user here</notice>
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org