Skip to content

Commit cd8887f

Browse files
authored
JAMES-4057 Match attachment against file extensions (#2731)
1 parent c03d2fe commit cd8887f

File tree

3 files changed

+74
-8
lines changed

3 files changed

+74
-8
lines changed

mailbox/opensearch/src/main/java/org/apache/james/mailbox/opensearch/query/CriterionConverter.java

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,18 @@ private Query convertTextCriterion(SearchQuery.TextCriterion textCriterion) {
252252
}
253253
case FULL:
254254
if (useQueryStringQuery && QUERY_STRING_CONTROL_CHAR.matchesAnyOf(textCriterion.getOperator().getValue())) {
255-
return new SimpleQueryStringQuery.Builder()
256-
.fields(ImmutableList.of(JsonMessageConstants.TEXT_BODY, JsonMessageConstants.HTML_BODY, JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT))
257-
.query(textCriterion.getOperator().getValue())
258-
.build().toQuery();
255+
return new BoolQuery.Builder()
256+
.should(new SimpleQueryStringQuery.Builder()
257+
.fields(ImmutableList.of(JsonMessageConstants.TEXT_BODY, JsonMessageConstants.HTML_BODY, JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT))
258+
.query(textCriterion.getOperator().getValue())
259+
.build().toQuery())
260+
.should(new TermQuery.Builder()
261+
.field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION)
262+
.value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build())
263+
.build()
264+
.toQuery())
265+
.build()
266+
.toQuery();
259267
} else {
260268
return new BoolQuery.Builder()
261269
.should(new MatchQuery.Builder()
@@ -279,15 +287,28 @@ private Query convertTextCriterion(SearchQuery.TextCriterion textCriterion) {
279287
.operator(Operator.And)
280288
.build()
281289
.toQuery())
290+
.should(new TermQuery.Builder()
291+
.field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION)
292+
.value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build())
293+
.build()
294+
.toQuery())
282295
.build()
283296
.toQuery();
284297
}
285298
case ATTACHMENTS:
286299
if (useQueryStringQuery) {
287-
return new SimpleQueryStringQuery.Builder()
288-
.fields(ImmutableList.of(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT))
289-
.query(textCriterion.getOperator().getValue())
290-
.build().toQuery();
300+
return new BoolQuery.Builder()
301+
.should(new SimpleQueryStringQuery.Builder()
302+
.fields(ImmutableList.of(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT))
303+
.query(textCriterion.getOperator().getValue())
304+
.build().toQuery())
305+
.should(new TermQuery.Builder()
306+
.field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION)
307+
.value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build())
308+
.build()
309+
.toQuery())
310+
.build()
311+
.toQuery();
291312
} else {
292313
return new BoolQuery.Builder()
293314
.should(new MatchQuery.Builder()
@@ -297,6 +318,11 @@ private Query convertTextCriterion(SearchQuery.TextCriterion textCriterion) {
297318
.operator(Operator.And)
298319
.build()
299320
.toQuery())
321+
.should(new TermQuery.Builder()
322+
.field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION)
323+
.value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build())
324+
.build()
325+
.toQuery())
300326
.build()
301327
.toQuery();
302328
}
@@ -309,6 +335,11 @@ private Query convertTextCriterion(SearchQuery.TextCriterion textCriterion) {
309335
.operator(Operator.And)
310336
.build()
311337
.toQuery())
338+
.should(new TermQuery.Builder()
339+
.field(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.FILE_EXTENSION)
340+
.value(new FieldValue.Builder().stringValue(textCriterion.getOperator().getValue()).build())
341+
.build()
342+
.toQuery())
312343
.build()
313344
.toQuery();
314345
default:

mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchIntegrationTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,34 @@ void multiMailboxSearchShouldBeSupportedWhenUsersHaveManyMailboxes() throws Exce
507507
.containsOnly(messageId2.getMessageId());
508508
}
509509

510+
@Test
511+
void shouldMatchFileExtension() throws Exception {
512+
MailboxPath mailboxPath = MailboxPath.forUser(USERNAME, INBOX);
513+
MailboxSession session = MailboxSessionUtil.create(USERNAME);
514+
MessageManager messageManager = storeMailboxManager.getMailbox(mailboxPath, session);
515+
516+
messageManager.appendMessage(
517+
MessageManager.AppendCommand.builder().build(
518+
Message.Builder
519+
.of()
520+
.setSubject("test")
521+
.setBody("testmail", StandardCharsets.UTF_8)
522+
.addField(new RawField("To", "alice@domain.tld"))
523+
.build()),
524+
session).getId();
525+
526+
ComposedMessageId messageId2 = messageManager.appendMessage(
527+
MessageManager.AppendCommand.builder()
528+
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/attachments-filename-in-content-type.eml")),
529+
session).getId();
530+
531+
awaitForOpenSearch(QueryBuilders.matchAll().build().toQuery(), 15);
532+
Thread.sleep(500);
533+
534+
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.mailContains("txt")), session)).toStream())
535+
.containsOnly(messageId2.getUid());
536+
}
537+
510538
@Disabled("MAILBOX-403 Relaxed the matching constraints for email addresses in text bodies to reduce OpenSearch disk space usage")
511539
@Test
512540
public void textShouldNotMatchOtherAddressesOfTheSameDomain() {

mailbox/opensearch/src/test/java/org/apache/james/mailbox/opensearch/OpenSearchOptimizeMoveAndFuzzySearchIntegrationTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.james.mailbox.model.MailboxPath;
3131
import org.apache.james.mailbox.model.SearchQuery;
3232
import org.apache.james.mime4j.dom.Message;
33+
import org.junit.jupiter.api.Disabled;
3334
import org.junit.jupiter.api.Test;
3435
import org.opensearch.client.opensearch._types.query_dsl.QueryBuilders;
3536

@@ -88,4 +89,10 @@ void searchShouldBeLenientOnAdjacentCharactersTranspositions() throws Exception
8889
assertThat(Flux.from(messageManager.search(SearchQuery.of(SearchQuery.bodyContains("boyd")), session)).toStream())
8990
.containsExactly(composedMessageId.getUid());
9091
}
92+
93+
@Disabled("Fuzzyness makes the results wider")
94+
@Override
95+
void shouldMatchFileExtension() {
96+
97+
}
9198
}

0 commit comments

Comments
 (0)