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 a8b7894ae047a7a6458404659b4bbf955efe422a Author: Rémi Kowalski <[email protected]> AuthorDate: Thu Jul 16 12:01:28 2020 +0200 JAMES-3098 return error if invalid property requested --- .../contract/MailboxGetMethodContract.scala | 5 ++-- .../org/apache/james/jmap/mail/MailboxGet.scala | 5 +++- .../james/jmap/method/MailboxGetMethod.scala | 34 ++++++++++++++-------- .../org/apache/james/jmap/model/Invocation.scala | 20 +++++++++++++ 4 files changed, 48 insertions(+), 16 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 40471f3..6a255a2 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 @@ -41,7 +41,7 @@ import org.apache.james.mime4j.dom.Message import org.apache.james.modules.{ACLProbeImpl, MailboxProbeImpl, QuotaProbesImpl} import org.apache.james.utils.DataProbeImpl import org.hamcrest.Matchers._ -import org.junit.jupiter.api.{BeforeEach, Disabled, Tag, Test} +import org.junit.jupiter.api.{BeforeEach, Tag, Test} object MailboxGetMethodContract { private val ARGUMENTS: String = "methodResponses[0][1]" @@ -680,7 +680,6 @@ trait MailboxGetMethodContract { |}""".stripMargin) } - @Disabled("TODO") @Test def getMailboxesShouldNotIncludeNamespaceIfSharesCapabilityIsUsedAndNamespaceIsNotRequested(server: GuiceJamesServer): Unit = { val mailboxId: String = server.getProbe(classOf[MailboxProbeImpl]) @@ -743,7 +742,7 @@ trait MailboxGetMethodContract { | "methodResponses": [[ | "error", { | "type": "invalidArguments", - | "description": "The following properties [invalidProperty] do not exist" + | "description": "The following properties [invalidProperty] do not exist." |}, | "c1"]] |}""".stripMargin) 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 5d9b971..613d418 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 @@ -26,7 +26,10 @@ import org.apache.james.mailbox.model.MailboxId case class Ids(value: List[MailboxId]) -case class Properties(value: List[NonEmptyString]) +case class Properties(value: List[NonEmptyString]) { + def asSetOfString: Set[String] = value.map(_.toString()).toSet +} + case class MailboxGetRequest(accountId: AccountId, ids: Option[Ids], 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 b48e7a6..2423978 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 @@ -26,7 +26,7 @@ import org.apache.james.jmap.mail._ import org.apache.james.jmap.model.CapabilityIdentifier.CapabilityIdentifier import org.apache.james.jmap.model.Invocation.{Arguments, MethodName} import org.apache.james.jmap.model.State.INSTANCE -import org.apache.james.jmap.model.{Invocation, MailboxFactory} +import org.apache.james.jmap.model.{ErrorCode, Invocation, MailboxFactory} import org.apache.james.jmap.utils.quotas.{QuotaLoader, QuotaLoaderWithPreloadedDefaultFactory} import org.apache.james.mailbox.exception.MailboxNotFoundException import org.apache.james.mailbox.model.search.MailboxQuery @@ -57,17 +57,27 @@ class MailboxGetMethod @Inject() (serializer: Serializer, override def process(capabilities: Set[CapabilityIdentifier], invocation: Invocation, mailboxSession: MailboxSession): Publisher[Invocation] = { metricFactory.decoratePublisherWithTimerMetricLogP99(JMAP_RFC8621_PREFIX + methodName.value, asMailboxGetRequest(invocation.arguments) - .flatMap(mailboxGetRequest => getMailboxes(mailboxGetRequest, mailboxSession) - .reduce(MailboxGetResults(Set.empty, NotFound(Set.empty)), (result1: MailboxGetResults, result2: MailboxGetResults) => result1.merge(result2)) - .map(mailboxes => MailboxGetResponse( - accountId = mailboxGetRequest.accountId, - state = INSTANCE, - list = mailboxes.mailboxes.toList.sortBy(_.sortOrder), - notFound = mailboxes.notFound)) - .map(mailboxGetResponse => Invocation( - methodName = methodName, - arguments = Arguments(serializer.serialize(mailboxGetResponse, mailboxGetRequest.properties, capabilities).as[JsObject]), - methodCallId = invocation.methodCallId)))) + .flatMap(mailboxGetRequest => { + mailboxGetRequest.properties match { + case Some(properties) if !properties.asSetOfString.subsetOf(Mailbox.allProperties) => + SMono.just(Invocation.error(errorCode = ErrorCode.InvalidArguments, + description = Some(s"The following properties [${properties.asSetOfString.diff(Mailbox.allProperties).mkString(", ")}] do not exist."), + methodCallId = invocation.methodCallId)) + case _ => getMailboxes(mailboxGetRequest, mailboxSession) + .reduce(MailboxGetResults(Set.empty, NotFound(Set.empty)), (result1: MailboxGetResults, result2: MailboxGetResults) => result1.merge(result2)) + .map(mailboxes => MailboxGetResponse( + accountId = mailboxGetRequest.accountId, + state = INSTANCE, + list = mailboxes.mailboxes.toList.sortBy(_.sortOrder), + notFound = mailboxes.notFound)) + .map(mailboxGetResponse => Invocation( + methodName = methodName, + arguments = Arguments(serializer.serialize(mailboxGetResponse, mailboxGetRequest.properties, capabilities).as[JsObject]), + methodCallId = invocation.methodCallId)) + + } + } + )) } private def asMailboxGetRequest(arguments: Arguments): SMono[MailboxGetRequest] = { diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Invocation.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Invocation.scala index c46d95b..5e8ec02 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Invocation.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Invocation.scala @@ -18,6 +18,7 @@ * ***************************************************************/ package org.apache.james.jmap.model +import eu.timepit.refined.auto._ import eu.timepit.refined.types.string.NonEmptyString import org.apache.james.jmap.model.Invocation.{Arguments, MethodCallId, MethodName} import play.api.libs.json._ @@ -33,4 +34,23 @@ object Invocation { case class Arguments(value: JsObject) extends AnyVal case class MethodCallId(value: NonEmptyString) + + def error(errorCode: ErrorCode, description: Option[String], methodCallId: MethodCallId): Invocation = { + Invocation(MethodName("error"), + Arguments(JsObject(Seq("type" -> JsString(errorCode.code), "description" -> JsString(description.getOrElse(errorCode.defaultDescription))))), + methodCallId) + } +} + +sealed trait ErrorCode { + def code: String + def defaultDescription: String +} + +object ErrorCode { + case object InvalidArguments extends ErrorCode { + override def code: String = "invalidArguments" + + override def defaultDescription: String = "One of the arguments is of the wrong type or otherwise invalid, or a required argument is missing." + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
