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