You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2020/11/11 04:42:58 UTC
[james-project] 06/07: JAMES-3359 Allow mailbox parentId updates
when have child
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 c44d4fff2ca79b3315904cafa05d6e0abfdb123f
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Nov 3 12:20:41 2020 +0700
JAMES-3359 Allow mailbox parentId updates when have child
Looping prevention is enforced by ensuring the new parentId is not one of the childs
---
.../contract/MailboxSetMethodContract.scala | 34 ++++++++++++----------
.../jmap/method/MailboxSetUpdatePerformer.scala | 19 +++++++++---
2 files changed, 33 insertions(+), 20 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/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 c81aef5..3385e0d 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
@@ -5928,7 +5928,7 @@ trait MailboxSetMethodContract {
| "notUpdated": {
| "${mailboxId.serialize}": {
| "type": "invalidArguments",
- | "description": "${mailboxId.serialize} parentId property cannot be updated as this mailbox has child mailboxes",
+ | "description": "A mailbox parentId property can not be set to itself or one of its child",
| "properties": [
| "parentId"
| ]
@@ -7176,7 +7176,7 @@ trait MailboxSetMethodContract {
}
@Test
- def updatingParentIdShouldFailWhenMailboxHasAChild(server: GuiceJamesServer): Unit = {
+ def updatingParentIdShouldSucceedWhenMailboxHasAChild(server: GuiceJamesServer): Unit = {
val mailboxProbe = server.getProbe(classOf[MailboxProbeImpl])
val mailboxId: MailboxId = mailboxProbe.createMailbox(MailboxPath.forUser(BOB, "mailbox"))
mailboxProbe.createMailbox(MailboxPath.forUser(BOB, "mailbox.child"))
@@ -7217,20 +7217,22 @@ trait MailboxSetMethodContract {
assertThatJson(response).isEqualTo(
s"""{
- | "sessionState": "75128aab4b1b",
- | "methodResponses": [
- | ["Mailbox/set", {
- | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
- | "newState": "000001",
- | "notUpdated": {
- | "${mailboxId.serialize}": {
- | "type": "invalidArguments",
- | "description": "${mailboxId.serialize} parentId property cannot be updated as this mailbox has child mailboxes",
- | "properties": ["parentId"]
- | }
- | }
- | }, "c1"]
- | ]
+ | "sessionState": "75128aab4b1b",
+ | "methodResponses": [
+ | [
+ | "Mailbox/set",
+ | {
+ | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "newState": "000001",
+ | "updated": {
+ | "${mailboxId.serialize}": {
+ |
+ | }
+ | }
+ | },
+ | "c1"
+ | ]
+ | ]
|}""".stripMargin)
}
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetUpdatePerformer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetUpdatePerformer.scala
index 176324f..f208989 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetUpdatePerformer.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetUpdatePerformer.scala
@@ -28,8 +28,9 @@ import org.apache.james.jmap.json.MailboxSerializer
import org.apache.james.jmap.mail.MailboxGet.UnparsedMailboxId
import org.apache.james.jmap.mail.{InvalidPatchException, InvalidPropertyException, InvalidUpdateException, MailboxGet, MailboxPatchObject, MailboxSetRequest, MailboxSetResponse, MailboxUpdateResponse, NameUpdate, ParentIdUpdate, ServerSetPropertyException, UnsupportedPropertyUpdatedException, ValidatedMailboxPatchObject}
import org.apache.james.jmap.method.MailboxSetUpdatePerformer.{MailboxUpdateFailure, MailboxUpdateResult, MailboxUpdateResults, MailboxUpdateSuccess}
-import org.apache.james.mailbox.MailboxManager.RenameOption
+import org.apache.james.mailbox.MailboxManager.{MailboxSearchFetchType, RenameOption}
import org.apache.james.mailbox.exception.{InsufficientRightsException, MailboxExistsException, MailboxNameException, MailboxNotFoundException}
+import org.apache.james.mailbox.model.search.{MailboxQuery, PrefixedWildcard}
import org.apache.james.mailbox.model.{MailboxId, MailboxPath}
import org.apache.james.mailbox.{MailboxManager, MailboxSession, MessageManager, Role, SubscriptionManager}
import reactor.core.scala.publisher.{SFlux, SMono}
@@ -58,7 +59,6 @@ object MailboxSetUpdatePerformer {
case e: SystemMailboxChangeException => SetError.invalidArguments(SetErrorDescription("Invalid change to a system mailbox"), filter(Properties("name", "parentId")))
case e: LoopInMailboxGraphException => SetError.invalidArguments(SetErrorDescription("A mailbox parentId property can not be set to itself or one of its child"), Some(Properties("parentId")))
case e: InsufficientRightsException => SetError.invalidArguments(SetErrorDescription("Invalid change to a delegated mailbox"))
- case e: MailboxHasChildException => SetError.invalidArguments(SetErrorDescription(s"${e.mailboxId.serialize()} parentId property cannot be updated as this mailbox has child mailboxes"), Some(Properties("parentId")))
case e: IllegalArgumentException => SetError.invalidArguments(SetErrorDescription(e.getMessage), None)
case _ => SetError.serverFail(SetErrorDescription(exception.getMessage))
}
@@ -184,8 +184,19 @@ class MailboxSetUpdatePerformer @Inject()(serializer: MailboxSerializer,
val currentName = originalPath.getName(mailboxSession.getPathDelimiter)
parentIdUpdate.newId
.map(id => {
- if (mailboxManager.hasChildren(originalPath, mailboxSession)) {
- throw MailboxHasChildException(mailboxId)
+ val createsALoop = SFlux.fromPublisher(
+ mailboxManager.search(MailboxQuery.builder()
+ .userAndNamespaceFrom(originalPath)
+ .expression(new PrefixedWildcard(originalPath.getName + mailboxSession.getPathDelimiter))
+ .build(),
+ MailboxSearchFetchType.Minimal,
+ mailboxSession))
+ .filter(child => child.getId.equals(id))
+ .hasElements
+ .block()
+
+ if (createsALoop) {
+ throw LoopInMailboxGraphException(mailboxId)
}
val parentPath = mailboxManager.getMailbox(id, mailboxSession).getMailboxPath
parentPath.child(currentName, mailboxSession.getPathDelimiter)
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org