You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2020/09/29 01:21:32 UTC
[james-project] 11/14: JAMES-3377 Email/query: search by bcc
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 2772a727358716b68dea48a1c031f7486acc0831
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Sep 28 11:21:10 2020 +0700
JAMES-3377 Email/query: search by bcc
---
.../contract/EmailQueryMethodContract.scala | 152 ++++++++++++++++++++-
.../james/jmap/utils/search/MailboxFilter.scala | 2 +-
2 files changed, 152 insertions(+), 2 deletions(-)
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
index 50a4a8c..edc839d 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
@@ -1604,7 +1604,6 @@ trait EmailQueryMethodContract {
"someInThreadHaveKeyword",
"noneInThreadHaveKeyword",
"text",
- "bcc",
"subject",
"body"
))
@@ -3856,6 +3855,157 @@ trait EmailQueryMethodContract {
}
}
+ @Test
+ def bccShouldFilterResultsWhenAddress(server: GuiceJamesServer): Unit = {
+ server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB))
+ def messageBuilder = Message.Builder
+ .of
+ .setSubject("test")
+ .setBody("testmail", StandardCharsets.UTF_8)
+ val messageId1 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder
+ .setBcc(DefaultAddressParser.DEFAULT.parseMailbox("user@domain.tld"))
+ .build))
+ .getMessageId
+ val messageId2 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder
+ .setBcc(DefaultAddressParser.DEFAULT.parseMailbox("other@domain.tld"))
+ .build))
+ .getMessageId
+ val messageId3 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder
+ .setBcc(DefaultAddressParser.DEFAULT.parseMailbox("yet@other.tld"))
+ .build))
+ .getMessageId
+ val messageId4 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder
+ .setBcc(DefaultAddressParser.DEFAULT.parseMailbox("yet@other.tld"),
+ DefaultAddressParser.DEFAULT.parseMailbox("user@domain.tld"))
+ .build))
+ .getMessageId
+ val messageId5 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder.build))
+ .getMessageId
+ val messageId6 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder
+ .setBcc(DefaultAddressParser.DEFAULT.parseMailbox("\"User\" <us...@domain.tld>"))
+ .build))
+ .getMessageId
+ val messageId7 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder
+ .setBcc(DefaultAddressParser.DEFAULT.parseMailbox("\"user@domain.tld\" <ot...@domain.tld>"))
+ .build))
+ .getMessageId
+
+ val request =
+ s"""{
+ | "using": [
+ | "urn:ietf:params:jmap:core",
+ | "urn:ietf:params:jmap:mail"],
+ | "methodCalls": [[
+ | "Email/query",
+ | {
+ | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "filter" : {
+ | "bcc": "user@domain.tld"
+ | }
+ | },
+ | "c1"]]
+ |}""".stripMargin
+
+ awaitAtMostTenSeconds.untilAsserted { () =>
+ val response = `given`
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(request)
+ .when
+ .post
+ .`then`
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .extract
+ .body
+ .asString
+
+ assertThatJson(response)
+ .withOptions(new Options(IGNORING_ARRAY_ORDER))
+ .inPath("$.methodResponses[0][1].ids")
+ .isEqualTo(s"""["${messageId7.serialize}", "${messageId6.serialize}", "${messageId4.serialize}", "${messageId1.serialize}"]""")
+ }
+ }
+
+ @Test
+ def bccShouldFilterResultsWhenNotAnAddress(server: GuiceJamesServer): Unit = {
+ server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB))
+ def messageBuilder = Message.Builder
+ .of
+ .setSubject("test")
+ .setBody("testmail", StandardCharsets.UTF_8)
+ val messageId1 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder
+ .setBcc(DefaultAddressParser.DEFAULT.parseMailbox("user@domain.tld"))
+ .build))
+ .getMessageId
+ val messageId2 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder
+ .setBcc(DefaultAddressParser.DEFAULT.parseMailbox("\"Display\" <ot...@domain.tld>"))
+ .build))
+ .getMessageId
+ val messageId3 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder
+ .setBcc(DefaultAddressParser.DEFAULT.parseMailbox("display@other.tld"))
+ .build))
+ .getMessageId
+ val messageId4 = server.getProbe(classOf[MailboxProbeImpl])
+ .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().build(
+ messageBuilder.build))
+ .getMessageId
+
+ val request =
+ s"""{
+ | "using": [
+ | "urn:ietf:params:jmap:core",
+ | "urn:ietf:params:jmap:mail"],
+ | "methodCalls": [[
+ | "Email/query",
+ | {
+ | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "filter" : {
+ | "bcc": "Display"
+ | }
+ | },
+ | "c1"]]
+ |}""".stripMargin
+
+ awaitAtMostTenSeconds.untilAsserted { () =>
+ val response = `given`
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(request)
+ .when
+ .post
+ .`then`
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .extract
+ .body
+ .asString
+
+ assertThatJson(response)
+ .withOptions(new Options(IGNORING_ARRAY_ORDER))
+ .inPath("$.methodResponses[0][1].ids")
+ .isEqualTo(s"""["${messageId2.serialize}", "${messageId3.serialize}"]""")
+ }
+ }
+
@ParameterizedTest
@MethodSource(value = Array("jmapSystemKeywords"))
def listMailsNotBySystemKeywordShouldReturnOnlyMailsWithoutThisSystemKeyword(keywordFlag: Flags, keywordName: String, server: GuiceJamesServer): Unit = {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/search/MailboxFilter.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/search/MailboxFilter.scala
index 25753d1..ab92c58 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/search/MailboxFilter.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/search/MailboxFilter.scala
@@ -206,7 +206,7 @@ object MailboxFilter {
case object Bcc extends QueryFilter {
override def toQuery(builder: SearchQuery.Builder, request: EmailQueryRequest): Either[UnsupportedFilterException, SearchQuery.Builder] =
request.filter.flatMap(_.bcc) match {
- case Some(_) => Left(UnsupportedFilterException("bcc"))
+ case Some(bcc) => Right(builder.andCriteria(SearchQuery.address(AddressType.Bcc, bcc.value)))
case None => Right(builder)
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org