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 513d2cbe6d90b0f4f69ae4163d213af5dd4a49f5 Author: Benoit Tellier <[email protected]> AuthorDate: Fri Oct 23 16:19:14 2020 +0700 JAMES-3436 Email/set create - syntax error validation --- .../rfc8621/contract/EmailSetMethodContract.scala | 167 +++++++++++++++++++++ .../apache/james/jmap/method/EmailSetMethod.scala | 1 + 2 files changed, 168 insertions(+) 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/EmailSetMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailSetMethodContract.scala index 1730fd0..0e8595b 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailSetMethodContract.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailSetMethodContract.scala @@ -276,6 +276,173 @@ trait EmailSetMethodContract { } @Test + def createShouldRejectEmptyMailboxIds(server: GuiceJamesServer): Unit = { + val andrePath = MailboxPath.inbox(ANDRE) + val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(andrePath) + + val request = + s"""{ + | "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"], + | "methodCalls": [ + | ["Email/set", { + | "accountId": "$ACCOUNT_ID", + | "create": { + | "aaaaaa":{ + | "mailboxIds": {}, + | "subject": "Boredome comes from a boring mind!" + | } + | } + | }, "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) + .inPath("methodResponses[0][1].notCreated.aaaaaa") + .isEqualTo( + s"""{ + | "description": "mailboxIds need to have size 1", + | "type": "invalidArguments" + |}""".stripMargin) + } + + @Test + def createShouldRejectInvalidMailboxIds(server: GuiceJamesServer): Unit = { + val andrePath = MailboxPath.inbox(ANDRE) + val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(andrePath) + + val request = + s"""{ + | "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"], + | "methodCalls": [ + | ["Email/set", { + | "accountId": "$ACCOUNT_ID", + | "create": { + | "aaaaaa":{ + | "mailboxIds": { + | "invalid": true + | }, + | "subject": "Boredome comes from a boring mind!" + | } + | } + | }, "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) + .inPath("methodResponses[0][1].notCreated.aaaaaa") + .isEqualTo( + s"""{ + | "description": "List((/mailboxIds,List(JsonValidationError(List(For input string: \\"invalid\\"),ArraySeq()))))", + | "type": "invalidArguments" + |}""".stripMargin) + } + + @Test + def createShouldRejectNoMailboxIds(server: GuiceJamesServer): Unit = { + val andrePath = MailboxPath.inbox(ANDRE) + val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(andrePath) + + val request = + s"""{ + | "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"], + | "methodCalls": [ + | ["Email/set", { + | "accountId": "$ACCOUNT_ID", + | "create": { + | "aaaaaa":{ + | "subject": "Boredome comes from a boring mind!" + | } + | } + | }, "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) + .inPath("methodResponses[0][1].notCreated.aaaaaa") + .isEqualTo( + s"""{ + | "description": "List((/mailboxIds,List(JsonValidationError(List(error.path.missing),ArraySeq()))))", + | "type": "invalidArguments" + |}""".stripMargin) + } + + @Test + def createShouldRejectInvalidJson(server: GuiceJamesServer): Unit = { + val andrePath = MailboxPath.inbox(ANDRE) + val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(andrePath) + + val request = + s"""{ + | "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"], + | "methodCalls": [ + | ["Email/set", { + | "accountId": "$ACCOUNT_ID", + | "create": { + | "aaaaaa":{ + | "mailboxIds": { + | "${mailboxId.serialize}": true + | }, + | "subject": ["Boredome comes from a boring mind!"] + | } + | } + | }, "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) + .inPath("methodResponses[0][1].notCreated.aaaaaa") + .isEqualTo( + s"""{ + | "description": "List((/subject,List(JsonValidationError(List(error.expected.jsstring),ArraySeq()))))", + | "type": "invalidArguments" + |}""".stripMargin) + } + + @Test def createShouldSucceedIfDelegated(server: GuiceJamesServer): Unit = { val andrePath = MailboxPath.inbox(ANDRE) val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(andrePath) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala index 7bb499b..e95abb9 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala @@ -118,6 +118,7 @@ class EmailSetMethod @Inject()(serializer: EmailSetSerializer, case class CreationSuccess(clientId: EmailCreationId, response: EmailCreationResponse) extends CreationResult case class CreationFailure(clientId: EmailCreationId, e: Throwable) extends CreationResult { def asMessageSetError: SetError = e match { + case e: IllegalArgumentException => SetError.invalidArguments(SetErrorDescription(e.getMessage)) case e: MailboxNotFoundException => SetError.notFound(SetErrorDescription("Mailbox " + e.getMessage)) case _ => SetError.serverFail(SetErrorDescription(e.getMessage)) } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
