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 6d18bde689800ad2b4b24e228f5d09bd757c45e7 Author: LanKhuat <[email protected]> AuthorDate: Wed Nov 18 15:15:50 2020 +0700 JAMES-3450 Email/query reject invalid FilterOperator --- .../contract/EmailQueryMethodContract.scala | 100 +++++++++++++++++++++ .../james/jmap/json/EmailQuerySerializer.scala | 3 +- 2 files changed, 102 insertions(+), 1 deletion(-) 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 ff8ec97..69297ed 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 @@ -5496,6 +5496,106 @@ trait EmailQueryMethodContract { } @Test + def emailQueryShouldRejectFilterOperatorWithExtraFields(server: GuiceJamesServer): Unit = { + val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) + val requestDate = ZonedDateTime.now().minusDays(1) + + val request = + s"""{ + | "using": [ + | "urn:ietf:params:jmap:core", + | "urn:ietf:params:jmap:mail"], + | "methodCalls": [[ + | "Email/query", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "filter" : { + | "inMailbox": "${mailboxId.serialize}", + | "before": "${UTCDate(requestDate.plusHours(1)).asUTC.format(UTC_DATE_FORMAT)}", + | "operator": "AND", + | "conditions": [ + | { "hasKeyword": "custom" }, { "hasKeyword": "another_custom" } + | ] + | } + | }, + | "c1"]] + |}""".stripMargin + + 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": "invalidArguments", + | "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter\\",\\"messages\\":[\\"Expecting filterOperator to contain only operator and conditions\\"]}]}" + | }, + | "c1" + | ] + | ] + |}""".stripMargin) + } + + @Test + def emailQueryShouldRejectOperatorWithoutCondition(server: GuiceJamesServer): Unit = { + val request = + s"""{ + | "using": [ + | "urn:ietf:params:jmap:core", + | "urn:ietf:params:jmap:mail"], + | "methodCalls": [[ + | "Email/query", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "filter" : { + | "operator": "AND" + | } + | }, + | "c1"]] + |}""".stripMargin + + 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": "invalidArguments", + | "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter\\",\\"messages\\":[\\"Expecting filterOperator to contain only operator and conditions\\"]}]}" + | }, + | "c1" + | ] + | ] + |}""".stripMargin) + } + + @Test def inMailboxShouldBeRejectedWhenInOperator(server: GuiceJamesServer): Unit = { val message: Message = buildTestMessage val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailQuerySerializer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailQuerySerializer.scala index 7a12c2b..11ff719 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailQuerySerializer.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailQuerySerializer.scala @@ -101,7 +101,8 @@ class EmailQuerySerializer @Inject()(mailboxIdFactory: MailboxId.Factory) { private implicit val filterOperatorReads: Reads[FilterOperator] = Json.reads[FilterOperator] private implicit def filterQueryReads: Reads[FilterQuery] = { - case jsValue@JsObject(underlying) if underlying.contains("operator") => filterOperatorReads.reads(jsValue) + case JsObject(underlying) if underlying.contains("operator") && (!underlying.contains("conditions") || underlying.contains("conditions") && underlying.size > 2) => JsError("Expecting filterOperator to contain only operator and conditions") + case jsValue@JsObject(underlying) if underlying.contains("operator") && underlying.contains("conditions") && underlying.size.equals(2) => filterOperatorReads.reads(jsValue) case jsValue => filterConditionReads.reads(jsValue) } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
