This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 4b789e36a777b8c9c10ea004a7ae8666a2368eef Author: Rémi Kowalski <[email protected]> AuthorDate: Wed Sep 23 16:35:14 2020 +0200 JAMES-3387 validate accountId for email/query --- .../contract/EmailQueryMethodContract.scala | 243 +++++++-------------- .../org/apache/james/jmap/mail/EmailQuery.scala | 3 +- .../james/jmap/method/EmailQueryMethod.scala | 56 ++--- 3 files changed, 114 insertions(+), 188 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 dcd7a7e..4cfac72 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 @@ -66,7 +66,6 @@ object EmailQueryMethodContract { } } - trait EmailQueryMethodContract { private lazy val slowPacedPollInterval = ONE_HUNDRED_MILLISECONDS @@ -92,17 +91,63 @@ trait EmailQueryMethodContract { } @Test + def emailQueryShouldFailWhenWrongAccountId(server: GuiceJamesServer): Unit = { + val request = + s"""{ + | "using": [ + | "urn:ietf:params:jmap:core", + | "urn:ietf:params:jmap:mail"], + | "methodCalls": [[ + | "Email/query", + | { + | "accountId": "unknownAccountId" + | }, + | "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).isEqualTo( + s"""{ + | "sessionState": "75128aab4b1b", + | "methodResponses": [[ + | "error", + | { + | "type": "accountNotFound" + | }, + | "c1" + | ]] + |}""".stripMargin) + } + } + + private def buildTestMessage = { + Message.Builder + .of + .setSubject("test") + .setBody("testmail", StandardCharsets.UTF_8) + .build + } + + @Test def hasAttachmentShouldKeepMessageWithAttachmentWhenTrue(server: GuiceJamesServer): Unit = { val mailboxProbe = server.getProbe(classOf[MailboxProbeImpl]) mailboxProbe.createMailbox(MailboxPath.inbox(BOB)) val messageId1: MessageId = mailboxProbe .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.from( - Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build)) + buildTestMessage)) .getMessageId val messageId2: MessageId = mailboxProbe @@ -552,11 +597,7 @@ trait EmailQueryMethodContract { val messageId1: MessageId = mailboxProbe .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.from( - Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build)) + buildTestMessage)) .getMessageId val messageId2: MessageId = mailboxProbe @@ -621,11 +662,7 @@ trait EmailQueryMethodContract { .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() .withInternalDate(beforeRequestDate) - .build(Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build)) + .build(buildTestMessage)) .getMessageId val messageId2: MessageId = mailboxProbe @@ -638,11 +675,7 @@ trait EmailQueryMethodContract { .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() .withInternalDate(afterRequestDate) - .build(Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build)) + .build(buildTestMessage)) .getMessageId val messageId4: MessageId = mailboxProbe @@ -702,11 +735,7 @@ trait EmailQueryMethodContract { @Test def shouldListMailsInAllUserMailboxes(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -764,11 +793,7 @@ trait EmailQueryMethodContract { @Test def shouldNotListMailsFromOtherUserMailboxes(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(ANDRE, "other") server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -826,11 +851,7 @@ trait EmailQueryMethodContract { @Test def listMailsShouldBeSortedByDescendingOrderOfArrivalByDefault(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -1165,11 +1186,7 @@ trait EmailQueryMethodContract { @Test def listMailsShouldBeIdempotent(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -1224,11 +1241,7 @@ trait EmailQueryMethodContract { @Test def listMailsShouldBeSortedInAscendingOrderByDefault(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -1282,11 +1295,7 @@ trait EmailQueryMethodContract { @Test def listMailsShouldBeSortedInAscendingOrder(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage val now: Instant = Instant.now() server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") @@ -1341,11 +1350,7 @@ trait EmailQueryMethodContract { @Test def listMailsShouldBeSortedInDescendingOrder(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage val now: Instant = Instant.now() server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") @@ -1448,11 +1453,7 @@ trait EmailQueryMethodContract { @Test def shouldListMailsInASpecificUserMailboxes(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") val otherMailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -1823,11 +1824,7 @@ trait EmailQueryMethodContract { @Test def shouldReturnIllegalArgumentErrorForAnUnknownSpecificUserMailboxes(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") val otherMailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -2114,11 +2111,7 @@ trait EmailQueryMethodContract { @Test def shouldListMailsNotInASpecificUserMailboxes(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") val otherMailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -2166,11 +2159,7 @@ trait EmailQueryMethodContract { @Test def shouldListMailsNotInZeroMailboxes(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -2217,11 +2206,7 @@ trait EmailQueryMethodContract { @Test def listMailsInAFirstMailboxAndNotSomeOtherMailboxShouldReturnMailsInFirstMailbox(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage val inbox = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") val otherMailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -2270,11 +2255,7 @@ trait EmailQueryMethodContract { @Test def listMailsInAFirstMailboxAndNotInTheSameMailboxShouldReturnEmptyResult(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage val inbox = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") server.getProbe(classOf[MailboxProbeImpl]).createMailbox(otherMailboxPath) @@ -2323,11 +2304,7 @@ trait EmailQueryMethodContract { @Test def shouldListMailsReceivedBeforeADate(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val requestDate = ZonedDateTime.now().minusDays(1) val messageId1 = sendMessageToBobInbox(server, message, Date.from(requestDate.toInstant)) @@ -2375,11 +2352,7 @@ trait EmailQueryMethodContract { } @Test def shouldListMailsReceivedBeforeADateInclusively(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val requestDate = ZonedDateTime.now().minusDays(1) val messageId1 = sendMessageToBobInbox(server, message, Date.from(requestDate.toInstant)) @@ -2427,11 +2400,7 @@ trait EmailQueryMethodContract { @Test def shouldListMailsReceivedAfterADate(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(inbox(BOB)) val receivedDateMessage1 = ZonedDateTime.now().minusDays(1) sendMessageToBobInbox(server, message, Date.from(receivedDateMessage1.toInstant)) @@ -2480,11 +2449,7 @@ trait EmailQueryMethodContract { @Test def listMailsReceivedAfterADateShouldBeExclusive(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val receivedDateMessage1 = ZonedDateTime.now().minusDays(1) sendMessageToBobInbox(server, message, Date.from(receivedDateMessage1.toInstant)) @@ -2532,11 +2497,7 @@ trait EmailQueryMethodContract { @Test def shouldLimitResultByTheLimitProvidedByTheClient(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") val requestDate = Date.from(ZonedDateTime.now().minusDays(1).toInstant) @@ -2640,11 +2601,7 @@ trait EmailQueryMethodContract { @Test def theLimitshouldBeEnforcedByTheServerIfNoLimitProvidedByTheClient(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val allMessages = (0 to 300).toList.foldLeft(List[MessageId](), ZonedDateTime.now().minusYears(1))((acc, _) => { @@ -2694,11 +2651,7 @@ trait EmailQueryMethodContract { @Test def theLimitshouldBeEnforcedByTheServerIfAGreaterLimitProvidedByTheClient(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val allMessages = (0 to 300).toList.foldLeft(List[MessageId](), ZonedDateTime.now().minusYears(1))((acc, _) => { @@ -2749,11 +2702,7 @@ trait EmailQueryMethodContract { @Test def resultsShouldStartAtThePositionProvidedByTheClient(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val messageId1: MessageId = server.getProbe(classOf[MailboxProbeImpl]) .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() @@ -2814,11 +2763,7 @@ trait EmailQueryMethodContract { @Test def zeroPositionQueryShouldReturnItemsFromTheStart(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val messageId1: MessageId = server.getProbe(classOf[MailboxProbeImpl]) .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() @@ -2879,11 +2824,7 @@ trait EmailQueryMethodContract { @Test def resultsShouldBeEmptyWithoutErrorWhenThePositionProvidedByTheClientIsGreaterThanTheNumberOfResults(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val otherMailboxPath = MailboxPath.forUser(BOB, "other") val requestDate = Date.from(ZonedDateTime.now().minusDays(1).toInstant) @@ -2942,11 +2883,7 @@ trait EmailQueryMethodContract { @Test def shouldReturnAnIllegalArgumentExceptionIfThePositionIsNegative(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val requestDate = Date.from(ZonedDateTime.now().minusDays(1).toInstant) sendMessageToBobInbox(server, message, Date.from(requestDate.toInstant)) @@ -3005,11 +2942,7 @@ trait EmailQueryMethodContract { @ParameterizedTest @MethodSource(value = Array("jmapSystemKeywords")) def listMailsBySystemKeywordShouldReturnOnlyMailsWithThisSystemKeyword(keywordFlag: Flags, keywordName: String, server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val messageId = server.getProbe(classOf[MailboxProbeImpl]) .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().withFlags(keywordFlag).build(message)) @@ -3289,11 +3222,7 @@ trait EmailQueryMethodContract { @Test def listMailsByCustomKeywordShouldReturnOnlyMailsWithThisCustomKeyword(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) val messageId = server.getProbe(classOf[MailboxProbeImpl]) .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().withFlags(new Flags("custom")).build(message)) @@ -3340,11 +3269,7 @@ trait EmailQueryMethodContract { @ParameterizedTest @MethodSource(value = Array("jmapSystemKeywords")) def listMailsNotBySystemKeywordShouldReturnOnlyMailsWithoutThisSystemKeyword(keywordFlag: Flags, keywordName: String, server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) server.getProbe(classOf[MailboxProbeImpl]) .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().withFlags(keywordFlag).build(message)) @@ -3390,11 +3315,7 @@ trait EmailQueryMethodContract { @Test def listMailsNotByCustomKeywordShouldReturnOnlyMailsWithoutThisCustomKeyword(server: GuiceJamesServer): Unit = { - val message: Message = Message.Builder - .of - .setSubject("test") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message: Message = buildTestMessage server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) server.getProbe(classOf[MailboxProbeImpl]) .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder().withFlags(new Flags("custom")).build(message)) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala index e91530b..8ca075a 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala @@ -20,6 +20,7 @@ package org.apache.james.jmap.mail import org.apache.james.jmap.mail.Email.Size import org.apache.james.jmap.mail.IsAscending.{ASCENDING, DESCENDING} +import org.apache.james.jmap.method.WithAccountId import org.apache.james.jmap.model.Limit.Limit import org.apache.james.jmap.model.Position.Position import org.apache.james.jmap.model.{AccountId, CanCalculateChanges, Keyword, LimitUnparsed, PositionUnparsed, QueryState, UTCDate} @@ -67,7 +68,7 @@ case class EmailQueryRequest(accountId: AccountId, comparator: Option[Set[Comparator]], collapseThreads: Option[CollapseThreads], anchor: Option[Anchor], - anchorOffset: Option[AnchorOffset]) + anchorOffset: Option[AnchorOffset]) extends WithAccountId sealed trait SortProperty { def toSortClause: Either[UnsupportedSortException, SortClause] diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala index 0cf6810..4787cb3 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala @@ -37,7 +37,6 @@ import org.apache.james.mailbox.exception.MailboxNotFoundException import org.apache.james.mailbox.model.MultimailboxesSearchQuery import org.apache.james.mailbox.{MailboxManager, MailboxSession} import org.apache.james.metrics.api.MetricFactory -import org.reactivestreams.Publisher import play.api.libs.json.{JsError, JsSuccess} import reactor.core.scala.publisher.{SFlux, SMono} @@ -45,35 +44,38 @@ import scala.jdk.CollectionConverters._ class EmailQueryMethod @Inject() (serializer: EmailQuerySerializer, mailboxManager: MailboxManager, - metricFactory: MetricFactory, - sessionSupplier: SessionSupplier) extends Method { + val metricFactory: MetricFactory, + val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[EmailQueryRequest] { override val methodName: MethodName = MethodName("Email/query") override val requiredCapabilities: Capabilities = Capabilities(CORE_CAPABILITY, MAIL_CAPABILITY) - override def process(capabilities: Set[CapabilityIdentifier], invocation: Invocation, mailboxSession: MailboxSession, processingContext: ProcessingContext): Publisher[(Invocation, ProcessingContext)] = - metricFactory.decoratePublisherWithTimerMetricLogP99(JMAP_RFC8621_PREFIX + methodName.value, - asEmailQueryRequest(invocation.arguments) - .flatMap(processRequest(mailboxSession, invocation, _, capabilities)) - .onErrorResume { - case e: UnsupportedRequestParameterException => SMono.just(Invocation.error( - ErrorCode.InvalidArguments, - s"The following parameter ${e.unsupportedParam} is syntactically valid, but is not supported by the server.", - invocation.methodCallId)) - case e: UnsupportedSortException => SMono.just(Invocation.error( - ErrorCode.UnsupportedSort, - s"The sort ${e.unsupportedSort} is syntactically valid, but it includes a property the server does not support sorting on or a collation method it does not recognise.", - invocation.methodCallId)) - case e: UnsupportedFilterException => SMono.just(Invocation.error( - ErrorCode.UnsupportedFilter, - s"The filter ${e.unsupportedFilter} is syntactically valid, but the server cannot process it. If the filter was the result of a user’s search input, the client SHOULD suggest that the user simplify their search.", - invocation.methodCallId)) - case e: IllegalArgumentException => SMono.just(Invocation.error(ErrorCode.InvalidArguments, e.getMessage, invocation.methodCallId)) - case e: MailboxNotFoundException => SMono.just(Invocation.error(ErrorCode.InvalidArguments, e.getMessage, invocation.methodCallId)) - case e: Throwable => SMono.raiseError(e) - } - .map(invocationResult => (invocationResult, processingContext))) + override def doProcess(capabilities: Set[CapabilityIdentifier], invocation: Invocation, mailboxSession: MailboxSession, processingContext: ProcessingContext, request: EmailQueryRequest): SMono[(Invocation, ProcessingContext)] = { + processRequest(mailboxSession, invocation, request, capabilities) + .onErrorResume { + case e: UnsupportedRequestParameterException => SMono.just(Invocation.error( + ErrorCode.InvalidArguments, + s"The following parameter ${e.unsupportedParam} is syntactically valid, but is not supported by the server.", + invocation.methodCallId)) + case e: UnsupportedSortException => SMono.just(Invocation.error( + ErrorCode.UnsupportedSort, + s"The sort ${e.unsupportedSort} is syntactically valid, but it includes a property the server does not support sorting on or a collation method it does not recognise.", + invocation.methodCallId)) + case e: UnsupportedFilterException => SMono.just(Invocation.error( + ErrorCode.UnsupportedFilter, + s"The filter ${e.unsupportedFilter} is syntactically valid, but the server cannot process it. If the filter was the result of a user’s search input, the client SHOULD suggest that the user simplify their search.", + invocation.methodCallId)) + case e: IllegalArgumentException => SMono.just(Invocation.error(ErrorCode.InvalidArguments, e.getMessage, invocation.methodCallId)) + case e: MailboxNotFoundException => SMono.just(Invocation.error(ErrorCode.InvalidArguments, e.getMessage, invocation.methodCallId)) + case e: Throwable => SMono.raiseError(e) + } + .map(invocationResult => (invocationResult, processingContext)) + } + - private def processRequest(mailboxSession: MailboxSession, invocation: Invocation, request: EmailQueryRequest, capabilities: Set[CapabilityIdentifier]): SMono[Invocation] = { + private def processRequest(mailboxSession: MailboxSession, + invocation: Invocation, + request: EmailQueryRequest, + capabilities: Set[CapabilityIdentifier]): SMono[Invocation] = { searchQueryFromRequest(request, capabilities, mailboxSession) match { case Left(error) => SMono.raiseError(error) case Right(searchQuery) => for { @@ -84,6 +86,8 @@ class EmailQueryMethod @Inject() (serializer: EmailQuerySerializer, } } + override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): SMono[EmailQueryRequest] = asEmailQueryRequest(invocation.arguments) + private def executeQuery(mailboxSession: MailboxSession, request: EmailQueryRequest, searchQuery: MultimailboxesSearchQuery, position: Position, limitToUse: Limit): SMono[EmailQueryResponse] = { SFlux.fromPublisher(mailboxManager.search(searchQuery, mailboxSession, limitToUse)) .drop(position.value) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
