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 11716545eba563e1772846e7e044a68d669514e0 Author: LanKhuat <[email protected]> AuthorDate: Tue Aug 18 12:03:24 2020 +0700 JAMES-3359 Mailbox/set update rights reset should fail on delegated mailbox --- .../contract/MailboxSetMethodContract.scala | 169 ++++++++++++++++++++- .../james/jmap/method/MailboxSetMethod.scala | 1 + 2 files changed, 169 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/MailboxSetMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala index cd11387..f75160b 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala @@ -33,7 +33,7 @@ import org.apache.james.jmap.draft.MessageIdProbe import org.apache.james.jmap.http.UserCredential import org.apache.james.jmap.rfc8621.contract.Fixture._ import org.apache.james.mailbox.MessageManager.AppendCommand -import org.apache.james.mailbox.model.MailboxACL.Right +import org.apache.james.mailbox.model.MailboxACL.{EntryKey, Right} import org.apache.james.mailbox.model.{MailboxACL, MailboxId, MailboxPath} import org.apache.james.mime4j.dom.Message import org.apache.james.modules.{ACLProbeImpl, MailboxProbeImpl} @@ -3411,6 +3411,173 @@ trait MailboxSetMethodContract { } @Test + def updateShouldNotResetRightsInSharedMailboxes(server: GuiceJamesServer): Unit = { + val path = MailboxPath.forUser(ANDRE, "mailbox") + val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path) + + server.getProbe(classOf[ACLProbeImpl]) + .replaceRights(path, BOB.asString(), new MailboxACL.Rfc4314Rights(Right.Lookup)) + + val request = + s""" + |{ + | "using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ], + | "methodCalls": [ + | [ + | "Mailbox/set", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "update": { + | "${mailboxId.serialize()}": { + | "/sharedWith": { + | "${DAVID.asString()}":["r", "l", "w"], + | "${BOB.asString()}":["r", "l", "w", "a"] + | } + | } + | } + | }, + | "c1" + | ], + | ["Mailbox/get", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "ids": ["${mailboxId.serialize()}"] + | }, + | "c2"] + | ] + |} + |""".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( + s"""{ + | "sessionState": "75128aab4b1b", + | "methodResponses": [ + | ["Mailbox/set", { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "newState": "000001", + | "notUpdated": { + | "${mailboxId.serialize()}": { + | "type": "invalidArguments", + | "description": "Invalid change to a delegated mailbox" + | } + | } + | }, "c1"], + | ["Mailbox/get", { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "state": "000001", + | "list": [{ + | "id": "${mailboxId.serialize()}", + | "name": "mailbox", + | "sortOrder": 1000, + | "totalEmails": 0, + | "unreadEmails": 0, + | "totalThreads": 0, + | "unreadThreads": 0, + | "myRights": { + | "mayReadItems": false, + | "mayAddItems": false, + | "mayRemoveItems": false, + | "maySetSeen": false, + | "maySetKeywords": false, + | "mayCreateChild": false, + | "mayRename": false, + | "mayDelete": false, + | "maySubmit": false + | }, + | "isSubscribed": false, + | "namespace": "Delegated[[email protected]]", + | "rights": { + | "[email protected]": ["l"] + | } + | }], + | "notFound": [] + | }, "c2"] + | ] + |}""".stripMargin) + + assertThat(server.getProbe(classOf[ACLProbeImpl]).retrieveRights(path) + .getEntries) + .doesNotContainKeys(EntryKey.createUserEntryKey(ANDRE)) + } + + @Test + def updateShouldFailOnOthersMailbox(server: GuiceJamesServer): Unit = { + val path = MailboxPath.forUser(ANDRE, "mailbox") + val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path) + + val request = + s""" + |{ + | "using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ], + | "methodCalls": [ + | [ + | "Mailbox/set", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "update": { + | "${mailboxId.serialize()}": { + | "/sharedWith": { + | "${DAVID.asString()}":["r", "l", "w"], + | "${BOB.asString()}":["r", "l", "w", "a"] + | } + | } + | } + | }, + | "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( + s"""{ + | "sessionState": "75128aab4b1b", + | "methodResponses": [ + | ["Mailbox/set", { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "newState": "000001", + | "notUpdated": { + | "${mailboxId.serialize()}": { + | "type": "notFound", + | "description": "${mailboxId.serialize()} can not be found" + | } + | } + | }, "c1"] + | ] + |}""".stripMargin) + + assertThat(server.getProbe(classOf[ACLProbeImpl]).retrieveRights(path) + .getEntries) + .doesNotContainKeys(EntryKey.createUserEntryKey(ANDRE)) + } + + @Test def updateShouldFailWhenInvalidRightReset(server: GuiceJamesServer): Unit = { val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.forUser(BOB, "mailbox")) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala index 24bebd5..785f37b 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala @@ -128,6 +128,7 @@ case class UpdateFailure(mailboxId: UnparsedMailboxId, exception: Throwable) ext case e: InvalidUpdateException => MailboxSetError.invalidArgument(Some(SetErrorDescription(s"${e.cause}")), Some(Properties(List(e.property)))) case e: InvalidPropertyException => MailboxSetError.invalidPatch(Some(SetErrorDescription(s"${e.cause}"))) case e: SystemMailboxChangeException => MailboxSetError.invalidArgument(Some(SetErrorDescription("Invalid change to a system mailbox")), Some(Properties(List("/name")))) + case e: InsufficientRightsException => MailboxSetError.invalidArgument(Some(SetErrorDescription("Invalid change to a delegated mailbox")), None) case _ => MailboxSetError.serverFail(Some(SetErrorDescription(exception.getMessage)), None) } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
