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 5e0d014f137fd67d353cc210920ea032d253acb2 Author: Rémi Kowalski <[email protected]> AuthorDate: Wed Sep 23 15:59:40 2020 +0200 JAMES-3387 validate accountId for email/get --- .../rfc8621/contract/EmailGetMethodContract.scala | 39 ++++++++++++++++++++++ .../org/apache/james/jmap/mail/EmailGet.scala | 3 +- .../apache/james/jmap/method/EmailGetMethod.scala | 22 ++++++------ 3 files changed, 51 insertions(+), 13 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/EmailGetMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala index 61fb12f..0821e63 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala @@ -73,6 +73,45 @@ trait EmailGetMethodContract { def randomMessageId: MessageId @Test + def emailGetShouldFailWhenWrongAccountId(): Unit = { + val response = `given` + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body( + s"""{ + | "using": [ + | "urn:ietf:params:jmap:core", + | "urn:ietf:params:jmap:mail"], + | "methodCalls": [[ + | "Email/get", + | { + | "accountId": "unknownAccountId", + | "ids": [] + | }, + | "c1"]] + |}""".stripMargin) + .when + .post + .`then` + .statusCode(SC_OK) + .contentType(JSON) + .extract + .body + .asString + + assertThatJson(response).isEqualTo( + s"""{ + | "sessionState": "75128aab4b1b", + | "methodResponses": [[ + | "error", + | { + | "type": "accountNotFound" + | }, + | "c1" + | ]] + |}""".stripMargin) + } + + @Test def idsShouldBeMandatory(): Unit = { val response = `given` .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailGet.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailGet.scala index cd4ae81..96f3ea7 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailGet.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailGet.scala @@ -28,6 +28,7 @@ import eu.timepit.refined.types.string.NonEmptyString import org.apache.james.jmap.mail.Email.UnparsedEmailId import org.apache.james.jmap.mail.EmailGetRequest.MaxBodyValueBytes import org.apache.james.jmap.mail.EmailHeaders.SPECIFIC_HEADER_PREFIX +import org.apache.james.jmap.method.WithAccountId import org.apache.james.jmap.model.State.State import org.apache.james.jmap.model.{AccountId, Properties} import org.apache.james.mime4j.dom.Message @@ -74,7 +75,7 @@ case class EmailGetRequest(accountId: AccountId, fetchHTMLBodyValues: Option[FetchHTMLBodyValues], maxBodyValueBytes: Option[MaxBodyValueBytes], properties: Option[Properties], - bodyProperties: Option[Properties]) + bodyProperties: Option[Properties]) extends WithAccountId case class EmailNotFound(value: Set[UnparsedEmailId]) { def merge(other: EmailNotFound): EmailNotFound = EmailNotFound(this.value ++ other.value) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala index ecc4663..0dbae7e 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala @@ -37,7 +37,6 @@ import org.apache.james.jmap.routes.ProcessingContext import org.apache.james.mailbox.MailboxSession import org.apache.james.mailbox.model.MessageId import org.apache.james.metrics.api.MetricFactory -import org.reactivestreams.Publisher import org.slf4j.{Logger, LoggerFactory} import play.api.libs.json.{JsError, JsObject, JsSuccess} import reactor.core.scala.publisher.{SFlux, SMono} @@ -83,20 +82,19 @@ class EmailGetMethod @Inject() (readerFactory: EmailViewReaderFactory, messageIdFactory: MessageId.Factory, zoneIdProvider: ZoneIdProvider, previewFactory: Preview.Factory, - metricFactory: MetricFactory, - sessionSupplier: SessionSupplier) extends Method { + val metricFactory: MetricFactory, + val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[EmailGetRequest] { override val methodName = MethodName("Email/get") override val requiredCapabilities: Capabilities = Capabilities(CORE_CAPABILITY, MAIL_CAPABILITY) - override def process(capabilities: Set[CapabilityIdentifier], invocation: Invocation, mailboxSession: MailboxSession, processingContext: ProcessingContext, sessionSupplier: SessionSupplier): Publisher[(Invocation, ProcessingContext)] = - metricFactory.decoratePublisherWithTimerMetricLogP99(JMAP_RFC8621_PREFIX + methodName.value, - asEmailGetRequest(invocation.arguments) - .flatMap(computeResponseInvocation(_, invocation, mailboxSession)) - .onErrorResume({ - case e: IllegalArgumentException => 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: EmailGetRequest): SMono[(Invocation, ProcessingContext)] = { + computeResponseInvocation(request, invocation, mailboxSession).onErrorResume({ + case e: IllegalArgumentException => SMono.just(Invocation.error(ErrorCode.InvalidArguments, e.getMessage, invocation.methodCallId)) + case e: Throwable => SMono.raiseError(e) + }).map(invocationResult => (invocationResult, processingContext)) + } + + override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): SMono[EmailGetRequest] = asEmailGetRequest(invocation.arguments) private def computeResponseInvocation(request: EmailGetRequest, invocation: Invocation, mailboxSession: MailboxSession): SMono[Invocation] = validateProperties(request) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
