You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rc...@apache.org on 2020/08/10 02:47:50 UTC

[james-project] 20/23: JAMES-3098 Mailbox/get should not return delegated mailboxes when no sharing extension

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 <bt...@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-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org