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 8e6d0efbb67804b8ea662aa1a5c21bdd1fb3c236 Author: Benoit Tellier <[email protected]> AuthorDate: Mon Nov 16 13:57:36 2020 +0700 JAMES-3440 EmailQuery Limit & Position validation should not rely on Mono Synchronous checks needs to be represented via an Either --- .../scala/org/apache/james/jmap/core/Query.scala | 21 ++++++++++---------- .../james/jmap/method/EmailQueryMethod.scala | 23 ++++++++++++---------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Query.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Query.scala index 3e746d8..b5d0473 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Query.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Query.scala @@ -25,20 +25,19 @@ import eu.timepit.refined.auto._ import eu.timepit.refined.numeric.{NonNegative, Positive} import eu.timepit.refined.refineV import org.apache.james.mailbox.model.{MailboxId, MessageId} -import reactor.core.scala.publisher.SMono case class PositionUnparsed(value: Int) extends AnyVal object Position { type Position = Int Refined NonNegative val zero: Position = 0 - def validateRequestPosition(requestPosition: Option[PositionUnparsed]): SMono[Position] = { + def validateRequestPosition(requestPosition: Option[PositionUnparsed]): Either[IllegalArgumentException, Position] = { val refinedPosition : Option[Either[String, Position]] = requestPosition.map(position => refineV[NonNegative](position.value)) refinedPosition match { - case Some(Left(_)) => SMono.raiseError(new IllegalArgumentException(s"Negative position are not supported yet. ${requestPosition.map(_.value).getOrElse("")} was provided.")) - case Some(Right(position)) => SMono.just(position) - case None => SMono.just(Position.zero) + case Some(Left(_)) => Left(new IllegalArgumentException(s"Negative position are not supported yet. ${requestPosition.map(_.value).getOrElse("")} was provided.")) + case Some(Right(position)) => Right(position) + case None => Right(Position.zero) } } } @@ -46,16 +45,16 @@ object Position { case class LimitUnparsed(value: Long) extends AnyVal object Limit { - type Limit = Long Refined Positive - val default: Limit = 256L + type Limit = Int Refined Positive + val default: Limit = 256 - def validateRequestLimit(requestLimit: Option[LimitUnparsed]): SMono[Limit] = { + def validateRequestLimit(requestLimit: Option[LimitUnparsed]): Either[IllegalArgumentException, Limit] = { val refinedLimit : Option[Either[String, Limit]] = requestLimit.map(limit => refineV[Positive](limit.value)) refinedLimit match { - case Some(Left(_)) => SMono.raiseError(new IllegalArgumentException(s"The limit can not be negative. ${requestLimit.map(_.value).getOrElse("")} was provided.")) - case Some(Right(limit)) if limit.value < default.value => SMono.just(limit) - case _ => SMono.just(default) + case Some(Left(_)) => Left(new IllegalArgumentException(s"The limit can not be negative. ${requestLimit.map(_.value).getOrElse("")} was provided.")) + case Some(Right(limit)) if limit.value < default.value => Right(limit) + case _ => Right(default) } } } 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 895d890..b2bfb02 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 @@ -54,16 +54,19 @@ class EmailQueryMethod @Inject() (serializer: EmailQuerySerializer, 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 { - positionToUse <- Position.validateRequestPosition(request.position) - limitToUse <- Limit.validateRequestLimit(request.limit) - response <- executeQuery(mailboxSession, request, searchQuery, positionToUse, limitToUse) - } yield Invocation(methodName = methodName, arguments = Arguments(serializer.serialize(response)), methodCallId = invocation.methodCallId) - } - } + capabilities: Set[CapabilityIdentifier]): SMono[Invocation] = + searchQueryFromRequest(request, capabilities, mailboxSession) + .flatMap(searchQuery => Limit.validateRequestLimit(request.limit).map((searchQuery, _))) + .flatMap { + case (searchQuery, limit) => Position.validateRequestPosition(request.position) + .map((searchQuery, limit, _)) + }.map { + case (searchQuery, limitToUse, positionToUse) => executeQuery(mailboxSession, request, searchQuery, positionToUse, limitToUse) + .map(response => Invocation( + methodName = methodName, + arguments = Arguments(serializer.serialize(response)), + methodCallId = invocation.methodCallId)) + }.fold(SMono.raiseError, res => res) override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): SMono[EmailQueryRequest] = asEmailQueryRequest(invocation.arguments) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
