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 a90dfe849f7df882d01aacc366cfc397cb851eaa Author: Benoit Tellier <btell...@linagora.com> AuthorDate: Thu Jul 30 16:45:55 2020 +0700 JAMES-3098 Mailbox/get should not return delegated mailboxes when no sharing extension --- .../contract/MailboxGetMethodContract.scala | 74 +++++++++++++++++++++- .../james/jmap/method/MailboxGetMethod.scala | 72 +++++++++++++++------ 2 files changed, 122 insertions(+), 24 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 19b2e37..0e4a2af 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 @@ -718,6 +718,71 @@ trait MailboxGetMethodContract { @Test @Tag(CategoryTags.BASIC_FEATURE) + def getMailboxesShouldReturnNotFoundWhenSharedMailboxAndNoExtension(server: GuiceJamesServer): Unit = { + val sharedMailboxName = "AndreShared" + val andreMailboxPath = MailboxPath.forUser(ANDRE, sharedMailboxName) + val mailboxId: String = server.getProbe(classOf[MailboxProbeImpl]) + .createMailbox(andreMailboxPath) + .serialize + + server.getProbe(classOf[ACLProbeImpl]) + .replaceRights(andreMailboxPath, BOB.asString, new MailboxACL.Rfc4314Rights(Right.Lookup)) + + `given` + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body(s"""{ + | "using": [ + | "urn:ietf:params:jmap:core", + | "urn:ietf:params:jmap:mail"], + | "methodCalls": [[ + | "Mailbox/get", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "ids": ["${mailboxId}"] + | }, + | "c1"]] + |}""".stripMargin) + .when + .post + .`then` + .statusCode(SC_OK) + .body(s"$ARGUMENTS.notFound", hasSize(1)) + .body(s"$ARGUMENTS.notFound[0]", equalTo(mailboxId)) + } + + @Test + def getMailboxesShouldNotIncludeDelegatedMailboxesWhenExtensionNotPresent(server: GuiceJamesServer): Unit = { + val sharedMailboxName = "AndreShared" + val andreMailboxPath = MailboxPath.forUser(ANDRE, sharedMailboxName) + server.getProbe(classOf[MailboxProbeImpl]) + .createMailbox(andreMailboxPath) + + server.getProbe(classOf[ACLProbeImpl]) + .replaceRights(andreMailboxPath, BOB.asString, new MailboxACL.Rfc4314Rights(Right.Lookup)) + + `given` + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body(s"""{ + | "using": [ + | "urn:ietf:params:jmap:core", + | "urn:ietf:params:jmap:mail"], + | "methodCalls": [[ + | "Mailbox/get", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6" + | }, + | "c1"]] + |}""".stripMargin) + .when + .post + .`then` + .statusCode(SC_OK) + // Only system mailboxes are included + .body(s"$ARGUMENTS.list", hasSize(6)) + } + + @Test + @Tag(CategoryTags.BASIC_FEATURE) def getMailboxesShouldNotReturnOtherPeopleRightsAsSharee(server: GuiceJamesServer): Unit = { val toUser1: String = "touser1@" + DOMAIN.asString val sharedMailboxName: String = "AndreShared" @@ -775,7 +840,8 @@ trait MailboxGetMethodContract { .body(s"""{ | "using": [ | "urn:ietf:params:jmap:core", - | "urn:ietf:params:jmap:mail"], + | "urn:ietf:params:jmap:mail", + | "urn:apache:james:params:jmap:mail:shares"], | "methodCalls": [[ | "Mailbox/get", | { @@ -817,7 +883,8 @@ trait MailboxGetMethodContract { .body(s"""{ | "using": [ | "urn:ietf:params:jmap:core", - | "urn:ietf:params:jmap:mail"], + | "urn:ietf:params:jmap:mail", + | "urn:apache:james:params:jmap:mail:shares"], | "methodCalls": [[ | "Mailbox/get", | { @@ -847,7 +914,8 @@ trait MailboxGetMethodContract { .body(s"""{ | "using": [ | "urn:ietf:params:jmap:core", - | "urn:ietf:params:jmap:mail"], + | "urn:ietf:params:jmap:mail", + | "urn:apache:james:params:jmap:mail:shares"], | "methodCalls": [[ | "Mailbox/get", | { 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 2423978..a310240 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.{ErrorCode, Invocation, MailboxFactory} +import org.apache.james.jmap.model.{CapabilityIdentifier, 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 @@ -63,7 +63,7 @@ class MailboxGetMethod @Inject() (serializer: Serializer, 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) + case _ => getMailboxes(capabilities, mailboxGetRequest, mailboxSession) .reduce(MailboxGetResults(Set.empty, NotFound(Set.empty)), (result1: MailboxGetResults, result2: MailboxGetResults) => result1.merge(result2)) .map(mailboxes => MailboxGetResponse( accountId = mailboxGetRequest.accountId, @@ -87,45 +87,75 @@ class MailboxGetMethod @Inject() (serializer: Serializer, } } - private def getMailboxes(mailboxGetRequest: MailboxGetRequest, + private def getMailboxes(capabilities: Set[CapabilityIdentifier], + mailboxGetRequest: MailboxGetRequest, mailboxSession: MailboxSession): SFlux[MailboxGetResults] = mailboxGetRequest.ids match { - case None => getAllMailboxes(mailboxSession).map(MailboxGetResults.found) + case None => getAllMailboxes(capabilities, mailboxSession) + .map(MailboxGetResults.found) case Some(ids) => SFlux.fromIterable(ids.value) - .flatMap(id => getMailboxResultById(id, mailboxSession)) + .flatMap(id => getMailboxResultById(capabilities, id, mailboxSession)) } - private def getMailboxResultById(mailboxId: MailboxId, mailboxSession: MailboxSession): SMono[MailboxGetResults] = + private def getMailboxResultById(capabilities: Set[CapabilityIdentifier], + mailboxId: MailboxId, + mailboxSession: MailboxSession): SMono[MailboxGetResults] = quotaFactory.loadFor(mailboxSession) .flatMap(quotaLoader => mailboxFactory.create(mailboxId, mailboxSession, quotaLoader) - .map(MailboxGetResults.found) + .map(mailbox => filterShared(capabilities, mailbox)) .onErrorResume { case _: MailboxNotFoundException => SMono.just(MailboxGetResults.notFound(mailboxId)) case error => SMono.raiseError(error) }) .subscribeOn(Schedulers.elastic) - private def getAllMailboxes(mailboxSession: MailboxSession): SFlux[Mailbox] = { + private def filterShared(capabilities: Set[CapabilityIdentifier], mailbox: Mailbox): MailboxGetResults = { + if (capabilities.contains(CapabilityIdentifier.JAMES_SHARES)) { + MailboxGetResults.found(mailbox) + } else { + mailbox.namespace match { + case _: PersonalNamespace => MailboxGetResults.found(mailbox) + case _ => MailboxGetResults.notFound(mailbox.id) + } + } + } + + private def getAllMailboxes(capabilities: Set[CapabilityIdentifier], mailboxSession: MailboxSession): SFlux[Mailbox] = { quotaFactory.loadFor(mailboxSession) .subscribeOn(Schedulers.elastic) .flatMapMany(quotaLoader => - getAllMailboxesMetaData(mailboxSession).flatMapMany(mailboxesMetaData => - SFlux.fromIterable(mailboxesMetaData) - .flatMap(mailboxMetaData => - getMailboxResult(mailboxMetaData = mailboxMetaData, - mailboxSession = mailboxSession, - allMailboxesMetadata = mailboxesMetaData, - quotaLoader = quotaLoader)))) + getAllMailboxesMetaData(capabilities, mailboxSession) + .flatMapMany(mailboxesMetaData => + SFlux.fromIterable(mailboxesMetaData) + .flatMap(mailboxMetaData => + getMailboxResult(mailboxMetaData = mailboxMetaData, + mailboxSession = mailboxSession, + allMailboxesMetadata = mailboxesMetaData, + quotaLoader = quotaLoader)))) } - private def getAllMailboxesMetaData(mailboxSession: MailboxSession): SMono[Seq[MailboxMetaData]] = - SFlux.fromPublisher(mailboxManager.search(MailboxQuery.builder.matchesAllMailboxNames.build, mailboxSession)) - .collectSeq() + private def getAllMailboxesMetaData(capabilities: Set[CapabilityIdentifier], mailboxSession: MailboxSession): SMono[Seq[MailboxMetaData]] = + SFlux.fromPublisher(mailboxManager.search( + mailboxQuery(capabilities, mailboxSession), + mailboxSession)) + .collectSeq() + + private def mailboxQuery(capabilities: Set[CapabilityIdentifier], mailboxSession: MailboxSession) = + if (capabilities.contains(CapabilityIdentifier.JAMES_SHARES)) { + MailboxQuery.builder + .matchesAllMailboxNames + .build + } else { + MailboxQuery.builder + .privateNamespace() + .user(mailboxSession.getUser) + .build + } private def getMailboxResult(mailboxSession: MailboxSession, - allMailboxesMetadata: Seq[MailboxMetaData], - mailboxMetaData: MailboxMetaData, - quotaLoader: QuotaLoader): SMono[Mailbox] = + allMailboxesMetadata: Seq[MailboxMetaData], + mailboxMetaData: MailboxMetaData, + quotaLoader: QuotaLoader): SMono[Mailbox] = mailboxFactory.create(mailboxMetaData = mailboxMetaData, mailboxSession = mailboxSession, allMailboxesMetadata = allMailboxesMetadata, --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org