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 60732e18edfb709509681ca8fcc376fd340bf425 Author: Rémi Kowalski <[email protected]> AuthorDate: Thu Sep 24 14:46:20 2020 +0200 JAMES-3387 validate accountId for mailbox/get --- .../contract/MailboxGetMethodContract.scala | 41 ++++++++++++++++++++ .../org/apache/james/jmap/mail/MailboxGet.scala | 3 +- .../james/jmap/method/MailboxGetMethod.scala | 45 ++++++++++------------ 3 files changed, 63 insertions(+), 26 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/MailboxGetMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxGetMethodContract.scala index 3da44bd..843460f 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxGetMethodContract.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxGetMethodContract.scala @@ -74,6 +74,47 @@ trait MailboxGetMethodContract { } @Test + def mailboxGetShouldFailWhenWrongAccountId(): Unit = { + val request = + s"""{ + | "using": [ + | "urn:ietf:params:jmap:core", + | "urn:ietf:params:jmap:mail", + | "urn:ietf:params:jmap:vacationresponse"], + | "methodCalls": [[ + | "Mailbox/get", + | { + | "accountId": "unknownAccountId", + | "ids": null + | }, + | "c1"]] + |}""".stripMargin + + val response = `given` + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body(request) + .when + .post + .`then` + .log().ifValidationFails() + .statusCode(SC_OK) + .contentType(JSON) + .extract + .body + .asString + + assertThatJson(response).isEqualTo( + """{ + | "sessionState": "75128aab4b1b", + | "methodResponses": [ + | ["error", { + | "type": "accountNotFound" + | }, "c1"] + | ] + |}""".stripMargin) + } + + @Test def getMailboxesShouldIncludeRightsAndNamespaceIfSharesCapabilityIsUsed(server: GuiceJamesServer): Unit = { val mailboxId: String = server.getProbe(classOf[MailboxProbeImpl]) .createMailbox(MailboxPath.forUser(BOB, "custom")) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala index d36a430..b230a77 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala @@ -20,6 +20,7 @@ package org.apache.james.jmap.mail import org.apache.james.jmap.mail.MailboxSetRequest.UnparsedMailboxId +import org.apache.james.jmap.method.WithAccountId import org.apache.james.jmap.model.State.State import org.apache.james.jmap.model.{AccountId, Properties} @@ -27,7 +28,7 @@ case class Ids(value: List[UnparsedMailboxId]) case class MailboxGetRequest(accountId: AccountId, ids: Option[Ids], - properties: Option[Properties]) + properties: Option[Properties]) extends WithAccountId case class NotFound(value: Set[UnparsedMailboxId]) { def merge(other: NotFound): NotFound = NotFound(this.value ++ other.value) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala index d747717..15c01c9 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala @@ -37,7 +37,6 @@ import org.apache.james.mailbox.model.search.MailboxQuery import org.apache.james.mailbox.model.{MailboxId, MailboxMetaData} import org.apache.james.mailbox.{MailboxManager, MailboxSession, SubscriptionManager} import org.apache.james.metrics.api.MetricFactory -import org.reactivestreams.Publisher import play.api.libs.json.{JsError, JsObject, JsSuccess} import reactor.core.scala.publisher.{SFlux, SMono} import reactor.core.scheduler.Schedulers @@ -50,8 +49,8 @@ class MailboxGetMethod @Inject() (serializer: MailboxSerializer, quotaFactory : QuotaLoaderWithPreloadedDefaultFactory, mailboxIdFactory: MailboxId.Factory, mailboxFactory: MailboxFactory, - metricFactory: MetricFactory, - val sessionSupplier: SessionSupplier) extends Method { + val metricFactory: MetricFactory, + val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[MailboxGetRequest] { override val methodName: MethodName = MethodName("Mailbox/get") override val requiredCapabilities: Capabilities = Capabilities(CORE_CAPABILITY, MAIL_CAPABILITY) @@ -73,30 +72,26 @@ class MailboxGetMethod @Inject() (serializer: MailboxSerializer, notFound = notFound) } - override def process(capabilities: Set[CapabilityIdentifier], - invocation: InvocationWithContext, - mailboxSession: MailboxSession): Publisher[InvocationWithContext] = { - metricFactory.decoratePublisherWithTimerMetricLogP99(JMAP_RFC8621_PREFIX + methodName.value, - asMailboxGetRequest(invocation.invocation.arguments) - .flatMap(mailboxGetRequest => { - val requestedProperties: Properties = mailboxGetRequest.properties.getOrElse(Mailbox.allProperties) - requestedProperties -- Mailbox.allProperties match { - case invalidProperties if invalidProperties.isEmpty() => getMailboxes(capabilities, mailboxGetRequest, invocation.processingContext, mailboxSession) - .reduce(MailboxGetResults.empty(), MailboxGetResults.merge) - .map(mailboxes => mailboxes.asResponse(mailboxGetRequest.accountId)) - .map(mailboxGetResponse => Invocation( - methodName = methodName, - arguments = Arguments(serializer.serialize(mailboxGetResponse, requestedProperties, capabilities).as[JsObject]), - methodCallId = invocation.invocation.methodCallId)) - case invalidProperties: Properties => - SMono.just(Invocation.error(errorCode = ErrorCode.InvalidArguments, - description = s"The following properties [${invalidProperties.format()}] do not exist.", - methodCallId = invocation.invocation.methodCallId)) - } - }) - .map(InvocationWithContext(_, invocation.processingContext))) + override def doProcess(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession, request: MailboxGetRequest): SMono[InvocationWithContext] = { + val requestedProperties: Properties = request.properties.getOrElse(Mailbox.allProperties) + (requestedProperties -- Mailbox.allProperties match { + case invalidProperties if invalidProperties.isEmpty() => getMailboxes(capabilities, request, invocation.processingContext, mailboxSession) + .reduce(MailboxGetResults.empty(), MailboxGetResults.merge) + .map(mailboxes => mailboxes.asResponse(request.accountId)) + .map(mailboxGetResponse => Invocation( + methodName = methodName, + arguments = Arguments(serializer.serialize(mailboxGetResponse, requestedProperties, capabilities).as[JsObject]), + methodCallId = invocation.invocation.methodCallId)) + case invalidProperties: Properties => + SMono.just(Invocation.error(errorCode = ErrorCode.InvalidArguments, + description = s"The following properties [${invalidProperties.format()}] do not exist.", + methodCallId = invocation.invocation.methodCallId)) + }).map(InvocationWithContext(_, invocation.processingContext)) + } + override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): SMono[MailboxGetRequest] = asMailboxGetRequest(invocation.arguments) + private def asMailboxGetRequest(arguments: Arguments): SMono[MailboxGetRequest] = { serializer.deserializeMailboxGetRequest(arguments.value) match { case JsSuccess(mailboxGetRequest, _) => SMono.just(mailboxGetRequest) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
