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
The following commit(s) were added to refs/heads/master by this push:
new fcc8181eb4 [JMAP] - Fix - The `Mailbox/set` method for shared
mailboxes must require share capability (#2647)
fcc8181eb4 is described below
commit fcc8181eb4f4d441f7f798cefc46c373aedf3a8c
Author: vttran <[email protected]>
AuthorDate: Mon Feb 24 20:04:54 2025 +0700
[JMAP] - Fix - The `Mailbox/set` method for shared mailboxes must require
share capability (#2647)
---
.../contract/MailboxSetMethodContract.scala | 18 ++--
.../jmap/method/MailboxSetCreatePerformer.scala | 36 ++++----
.../jmap/method/MailboxSetDeletePerformer.scala | 17 ++--
.../james/jmap/method/MailboxSetMethod.scala | 15 +++-
.../jmap/method/MailboxSetUpdatePerformer.scala | 95 ++++++++++++----------
5 files changed, 104 insertions(+), 77 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 2e92c93fd1..735e509507 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
@@ -2122,7 +2122,7 @@ trait MailboxSetMethodContract {
val request =
s"""
|{
- | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ],
| "methodCalls": [
| [
| "Mailbox/set",
@@ -2185,7 +2185,7 @@ trait MailboxSetMethodContract {
val request =
s"""
|{
- | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ],
| "methodCalls": [
| [
| "Mailbox/set",
@@ -2643,7 +2643,7 @@ trait MailboxSetMethodContract {
val request =
s"""
|{
- | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ],
| "methodCalls": [
| [
| "Mailbox/set",
@@ -2691,7 +2691,7 @@ trait MailboxSetMethodContract {
}
@Test
- def deleteShouldSuccessWhenHasRight(server: GuiceJamesServer): Unit = {
+ def deleteSharedMailboxShouldSuccessWhenHasRight(server: GuiceJamesServer):
Unit = {
val path = MailboxPath.forUser(ANDRE, "mailbox")
val mailboxId: MailboxId =
server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path)
server.getProbe(classOf[ACLProbeImpl])
@@ -2700,7 +2700,7 @@ trait MailboxSetMethodContract {
val request =
s"""
|{
- | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ],
| "methodCalls": [
| [
| "Mailbox/set",
@@ -3791,7 +3791,7 @@ trait MailboxSetMethodContract {
val request =
s"""
|{
- | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ],
| "methodCalls": [
| ["Mailbox/set",
| {
@@ -8121,7 +8121,7 @@ trait MailboxSetMethodContract {
val request = s"""
|{
- | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ],
| "methodCalls": [
| [
| "Mailbox/set",
@@ -8184,7 +8184,7 @@ trait MailboxSetMethodContract {
val request = s"""
|{
- | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ],
| "methodCalls": [
| [
| "Mailbox/set",
@@ -8247,7 +8247,7 @@ trait MailboxSetMethodContract {
val request = s"""
|{
- | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares" ],
| "methodCalls": [
| [
| "Mailbox/set",
diff --git
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetCreatePerformer.scala
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetCreatePerformer.scala
index a44db74a71..b12554d2a5 100644
---
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetCreatePerformer.scala
+++
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetCreatePerformer.scala
@@ -93,30 +93,29 @@ class MailboxSetCreatePerformer @Inject()(serializer:
MailboxSerializer,
val metricFactory: MetricFactory,
val sessionSupplier:
SessionSupplier) {
-
-
def createMailboxes(mailboxSession: MailboxSession,
- mailboxSetRequest: MailboxSetRequest,
- processingContext: ProcessingContext):
SMono[(MailboxCreationResults, ProcessingContext)] = {
+ mailboxSetRequest: MailboxSetRequest,
+ processingContext: ProcessingContext,
+ supportSharedMailbox: Boolean):
SMono[(MailboxCreationResults, ProcessingContext)] =
SFlux.fromIterable(mailboxSetRequest.create
- .getOrElse(Map.empty)
- .view)
- .fold((MailboxCreationResults(Nil), processingContext)){
- (acc : (MailboxCreationResults, ProcessingContext), elem:
(MailboxCreationId, JsObject)) => {
+ .getOrElse(Map.empty)
+ .view)
+ .fold((MailboxCreationResults(Nil), processingContext)) {
+ (acc: (MailboxCreationResults, ProcessingContext), elem:
(MailboxCreationId, JsObject)) => {
val (mailboxCreationId, jsObject) = elem
- val (creationResult, updatedProcessingContext) =
createMailbox(mailboxSession, mailboxCreationId, jsObject, acc._2)
+ val (creationResult, updatedProcessingContext) =
createMailbox(mailboxSession, mailboxCreationId, jsObject, acc._2,
supportSharedMailbox)
(MailboxCreationResults(acc._1.created :+ creationResult),
updatedProcessingContext)
}
}
.subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER)
- }
private def createMailbox(mailboxSession: MailboxSession,
mailboxCreationId: MailboxCreationId,
jsObject: JsObject,
- processingContext: ProcessingContext):
(MailboxCreationResult, ProcessingContext) = {
+ processingContext: ProcessingContext,
+ supportSharedMailbox: Boolean):
(MailboxCreationResult, ProcessingContext) = {
parseCreate(jsObject)
- .flatMap(mailboxCreationRequest => resolvePath(mailboxSession,
mailboxCreationRequest)
+ .flatMap(mailboxCreationRequest => resolvePath(mailboxSession,
mailboxCreationRequest, supportSharedMailbox)
.flatMap(path => createMailbox(mailboxSession = mailboxSession,
path = path,
mailboxCreationRequest = mailboxCreationRequest)))
@@ -136,7 +135,8 @@ class MailboxSetCreatePerformer @Inject()(serializer:
MailboxSerializer,
})
private def resolvePath(mailboxSession: MailboxSession,
- mailboxCreationRequest: MailboxCreationRequest):
Either[Exception, MailboxPath] = {
+ mailboxCreationRequest: MailboxCreationRequest,
+ supportSharedMailbox: Boolean): Either[Exception,
MailboxPath] = {
if
(mailboxCreationRequest.name.value.contains(mailboxSession.getPathDelimiter)) {
return Left(new MailboxNameException(s"The mailbox
'${mailboxCreationRequest.name.value}' contains an illegal character:
'${mailboxSession.getPathDelimiter}'"))
}
@@ -146,7 +146,8 @@ class MailboxSetCreatePerformer @Inject()(serializer:
MailboxSerializer,
.toEither
.left
.map(e => new IllegalArgumentException(e.getMessage, e))
- parentPath <- retrievePath(parentId, mailboxSession)
+ parentPathPreAssert <- retrievePath(parentId, mailboxSession)
+ parentPath <- validateCapabilityIfSharedMailbox(mailboxSession,
parentId, supportSharedMailbox).apply(parentPathPreAssert)
} yield {
parentPath.child(mailboxCreationRequest.name,
mailboxSession.getPathDelimiter)
})
@@ -159,6 +160,13 @@ class MailboxSetCreatePerformer @Inject()(serializer:
MailboxSerializer,
case e: Exception => Left(e)
}
+ private def validateCapabilityIfSharedMailbox(mailboxSession:
MailboxSession, id: MailboxId, supportSharedMailbox: Boolean): MailboxPath =>
Either[Exception, MailboxPath] =
+ mailboxPath => if (!mailboxPath.belongsTo(mailboxSession) &&
!supportSharedMailbox) {
+ Left(new MailboxNotFoundException(id))
+ } else {
+ Right(mailboxPath)
+ }
+
private def recordCreationIdInProcessingContext(mailboxCreationId:
MailboxCreationId,
processingContext:
ProcessingContext,
mailboxId: MailboxId):
Either[IllegalArgumentException, ProcessingContext] =
diff --git
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetDeletePerformer.scala
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetDeletePerformer.scala
index acf75a7b90..692fae435f 100644
---
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetDeletePerformer.scala
+++
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetDeletePerformer.scala
@@ -26,6 +26,7 @@ import org.apache.james.jmap.core.SetError
import org.apache.james.jmap.core.SetError.SetErrorDescription
import org.apache.james.jmap.mail.{MailboxGet, MailboxSetError,
MailboxSetRequest, RemoveEmailsOnDestroy, UnparsedMailboxId}
import
org.apache.james.jmap.method.MailboxSetDeletePerformer.{MailboxDeletionFailure,
MailboxDeletionResult, MailboxDeletionResults, MailboxDeletionSuccess}
+import
org.apache.james.jmap.method.MailboxSetMethod.assertCapabilityIfSharedMailbox
import org.apache.james.mailbox.exception.{InsufficientRightsException,
MailboxNotFoundException}
import org.apache.james.mailbox.model.{FetchGroup, MailboxId, MessageRange}
import org.apache.james.mailbox.{MailboxManager, MailboxSession,
MessageManager, Role, SubscriptionManager}
@@ -85,24 +86,25 @@ class MailboxSetDeletePerformer @Inject()(mailboxManager:
MailboxManager,
subscriptionManager:
SubscriptionManager,
mailboxIdFactory: MailboxId.Factory)
{
- def deleteMailboxes(mailboxSession: MailboxSession, mailboxSetRequest:
MailboxSetRequest): SMono[MailboxDeletionResults] =
+ def deleteMailboxes(mailboxSession: MailboxSession, mailboxSetRequest:
MailboxSetRequest, supportSharedMailbox: Boolean):
SMono[MailboxDeletionResults] =
SFlux.fromIterable(mailboxSetRequest.destroy.getOrElse(Seq()).toSet)
- .flatMap(id => delete(mailboxSession, id,
mailboxSetRequest.onDestroyRemoveEmails.getOrElse(RemoveEmailsOnDestroy(false)))
+ .flatMap(id => delete(mailboxSession, id,
mailboxSetRequest.onDestroyRemoveEmails.getOrElse(RemoveEmailsOnDestroy(false)),
supportSharedMailbox)
.onErrorRecover(e => MailboxDeletionFailure(id, e)),
maxConcurrency = 5)
.collectSeq()
.map(MailboxDeletionResults)
.doOnSuccess(auditTrail(mailboxSession, _))
- private def delete(mailboxSession: MailboxSession, id: UnparsedMailboxId,
onDestroy: RemoveEmailsOnDestroy): SMono[MailboxDeletionResult] =
+ private def delete(mailboxSession: MailboxSession, id: UnparsedMailboxId,
onDestroy: RemoveEmailsOnDestroy, supportSharedMailbox: Boolean):
SMono[MailboxDeletionResult] =
MailboxGet.parse(mailboxIdFactory)(id)
.fold(e => SMono.error(e),
- id => doDelete(mailboxSession, id, onDestroy)
+ id => doDelete(mailboxSession, id, onDestroy, supportSharedMailbox)
.`then`(SMono.just[MailboxDeletionResult](MailboxDeletionSuccess(id))))
- private def doDelete(mailboxSession: MailboxSession, id: MailboxId,
onDestroy: RemoveEmailsOnDestroy): SMono[Unit] =
+ private def doDelete(mailboxSession: MailboxSession, id: MailboxId,
onDestroy: RemoveEmailsOnDestroy, supportSharedMailbox: Boolean): SMono[Unit] =
SMono(mailboxManager.getMailboxReactive(id, mailboxSession))
- .flatMap((mailbox: MessageManager) =>
+ .filterWhen(assertCapabilityIfSharedMailbox(mailboxSession, id,
supportSharedMailbox))
+ .flatMap((mailbox: MessageManager) => {
SMono(mailboxManager.hasChildrenReactive(mailbox.getMailboxPath,
mailboxSession))
.flatMap(hasChildren => {
if (isASystemMailbox(mailbox)) {
@@ -128,7 +130,8 @@ class MailboxSetDeletePerformer @Inject()(mailboxManager:
MailboxManager,
.flatMap(deletedMailbox =>
SMono(subscriptionManager.unsubscribeReactive(deletedMailbox.generateAssociatedPath(),
mailboxSession)))
.`then`())
}
- }))
+ })
+ })
private def auditTrail(mailboxSession: MailboxSession,
mailboxDeletionResults: MailboxDeletionResults): Unit = {
if (mailboxDeletionResults.destroyed.nonEmpty) {
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 cb5d1884c7..fea82b2674 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
@@ -32,8 +32,9 @@ import
org.apache.james.jmap.method.MailboxSetCreatePerformer.MailboxCreationRes
import
org.apache.james.jmap.method.MailboxSetDeletePerformer.MailboxDeletionResults
import
org.apache.james.jmap.method.MailboxSetUpdatePerformer.MailboxUpdateResults
import org.apache.james.jmap.routes.SessionSupplier
-import org.apache.james.mailbox.MailboxSession
+import org.apache.james.mailbox.exception.MailboxNotFoundException
import org.apache.james.mailbox.model.MailboxId
+import org.apache.james.mailbox.{MailboxSession, MessageManager}
import org.apache.james.metrics.api.MetricFactory
import play.api.libs.json.JsObject
import reactor.core.scala.publisher.SMono
@@ -44,6 +45,13 @@ case class LoopInMailboxGraphException(mailboxId: MailboxId)
extends Exception
case class MailboxHasChildException(mailboxId: MailboxId) extends Exception
case class MailboxCreationParseException(setError: SetError) extends Exception
+object MailboxSetMethod {
+ def assertCapabilityIfSharedMailbox(mailboxSession: MailboxSession, id:
MailboxId, supportSharedMailbox: Boolean): MessageManager => SMono[Boolean] =
+ mailbox => if (!mailbox.getMailboxPath.belongsTo(mailboxSession) &&
!supportSharedMailbox)
+ SMono.error(new MailboxNotFoundException(id))
+ else SMono.just(true)
+}
+
class MailboxSetMethod @Inject()(serializer: MailboxSerializer,
createPerformer: MailboxSetCreatePerformer,
deletePerformer: MailboxSetDeletePerformer,
@@ -58,9 +66,10 @@ class MailboxSetMethod @Inject()(serializer:
MailboxSerializer,
override def doProcess(capabilities: Set[CapabilityIdentifier], invocation:
InvocationWithContext, mailboxSession: MailboxSession, request:
MailboxSetRequest): SMono[InvocationWithContext] = for {
oldState <- retrieveState(capabilities, mailboxSession)
- creationResults <- createPerformer.createMailboxes(mailboxSession,
request, invocation.processingContext)
+ supportSharedMailbox = capabilities.contains(JAMES_SHARES)
+ creationResults <- createPerformer.createMailboxes(mailboxSession,
request, invocation.processingContext, supportSharedMailbox)
updateResults <- updatePerformer.updateMailboxes(mailboxSession, request,
capabilities)
- deletionResults <- deletePerformer.deleteMailboxes(mailboxSession, request)
+ deletionResults <- deletePerformer.deleteMailboxes(mailboxSession,
request, supportSharedMailbox)
newState <- retrieveState(capabilities, mailboxSession)
response = createResponse(capabilities, invocation.invocation, request,
creationResults._1, deletionResults, updateResults, oldState, newState)
} yield InvocationWithContext(response, creationResults._2)
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 ad9844c45e..a757ca9e62 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
@@ -22,7 +22,7 @@ package org.apache.james.jmap.method
import com.google.common.collect.ImmutableMap
import eu.timepit.refined.auto._
import jakarta.inject.Inject
-import org.apache.james.jmap.core.CapabilityIdentifier.CapabilityIdentifier
+import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier,
JAMES_SHARES}
import org.apache.james.jmap.core.SetError.SetErrorDescription
import org.apache.james.jmap.core.{Properties, SetError}
import org.apache.james.jmap.json.MailboxSerializer
@@ -114,8 +114,8 @@ class MailboxSetUpdatePerformer @Inject()(serializer:
MailboxSerializer,
mailboxIdFactory: MailboxId.Factory)
{
def updateMailboxes(mailboxSession: MailboxSession,
- mailboxSetRequest: MailboxSetRequest,
- capabilities: Set[CapabilityIdentifier]):
SMono[MailboxUpdateResults] = {
+ mailboxSetRequest: MailboxSetRequest,
+ capabilities: Set[CapabilityIdentifier]):
SMono[MailboxUpdateResults] =
SFlux.fromIterable(mailboxSetRequest.update.getOrElse(Seq()))
.flatMap({
case (unparsedMailboxId: UnparsedMailboxId, patch: MailboxPatchObject)
=>
@@ -127,7 +127,6 @@ class MailboxSetUpdatePerformer @Inject()(serializer:
MailboxSerializer,
}, maxConcurrency = 5)
.collectSeq()
.map(MailboxUpdateResults)
- }
private def updateMailbox(mailboxSession: MailboxSession,
mailboxId: MailboxId,
@@ -135,23 +134,25 @@ class MailboxSetUpdatePerformer @Inject()(serializer:
MailboxSerializer,
patch: MailboxPatchObject,
capabilities: Set[CapabilityIdentifier]):
SMono[MailboxUpdateResult] = {
patch.validate(mailboxIdFactory, serializer, capabilities, mailboxSession)
- .fold(e => SMono.error(e), validatedPatch =>
- updateMailboxRights(mailboxId, validatedPatch, mailboxSession)
- .`then`(updateSubscription(mailboxId, validatedPatch,
mailboxSession))
- .`then`(updateMailboxPath(mailboxId, unparsedMailboxId,
validatedPatch, mailboxSession)))
+ .fold(e => SMono.error(e), validatedPatch => {
+ val supportSharedMailbox: Boolean = capabilities.contains(JAMES_SHARES)
+ getMessageManager(supportSharedMailbox, mailboxId, mailboxSession)
+ .flatMap(messageManager => updateMailboxRights(mailboxId,
validatedPatch, mailboxSession)
+ .`then`(updateSubscription(mailboxId, validatedPatch,
mailboxSession, messageManager))
+ .`then`(updateMailboxPath(mailboxId, unparsedMailboxId,
validatedPatch, mailboxSession, messageManager, supportSharedMailbox)))
+ })
}
- private def updateSubscription(mailboxId: MailboxId, validatedPatch:
ValidatedMailboxPatchObject, mailboxSession: MailboxSession):
SMono[MailboxUpdateResult] = {
+ private def updateSubscription(mailboxId: MailboxId, validatedPatch:
ValidatedMailboxPatchObject, mailboxSession: MailboxSession, messageManager:
MessageManager): SMono[MailboxUpdateResult] = {
validatedPatch.isSubscribedUpdate.map(isSubscribedUpdate => {
SMono.fromCallable(() => {
- val mailbox = mailboxManager.getMailbox(mailboxId, mailboxSession)
- val isOwner = mailbox.getMailboxPath.belongsTo(mailboxSession)
+ val isOwner = messageManager.getMailboxPath.belongsTo(mailboxSession)
val shouldSubscribe =
isSubscribedUpdate.isSubscribed.map(_.value).getOrElse(isOwner)
if (shouldSubscribe) {
- subscriptionManager.subscribe(mailboxSession, mailbox.getMailboxPath)
+ subscriptionManager.subscribe(mailboxSession,
messageManager.getMailboxPath)
} else {
- subscriptionManager.unsubscribe(mailboxSession,
mailbox.getMailboxPath)
+ subscriptionManager.unsubscribe(mailboxSession,
messageManager.getMailboxPath)
}
}).`then`(SMono.just[MailboxUpdateResult](MailboxUpdateSuccess(mailboxId)))
.subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER)
@@ -162,44 +163,44 @@ class MailboxSetUpdatePerformer @Inject()(serializer:
MailboxSerializer,
private def updateMailboxPath(mailboxId: MailboxId,
unparsedMailboxId: UnparsedMailboxId,
validatedPatch: ValidatedMailboxPatchObject,
- mailboxSession: MailboxSession):
SMono[MailboxUpdateResult] = {
+ mailboxSession: MailboxSession,
+ mailbox: MessageManager,
+ supportSharedMailbox: Boolean):
SMono[MailboxUpdateResult] = {
if (validatedPatch.shouldUpdateMailboxPath) {
- SMono(mailboxManager.getMailboxReactive(mailboxId, mailboxSession))
- .flatMap(mailbox =>
- SMono.fromCallable[MailboxUpdateResult](() => {
- try {
- if (isASystemMailbox(mailbox) &&
!DefaultMailboxes.INBOX.equalsIgnoreCase(mailbox.getMailboxPath.getName)) {
- throw SystemMailboxChangeException(mailboxId)
- }
- if
(validatedPatch.parentIdUpdate.flatMap(_.newId).contains(mailboxId)) {
- throw LoopInMailboxGraphException(mailboxId)
- }
- val oldPath = mailbox.getMailboxPath
- val newPath = applyParentIdUpdate(mailboxId,
validatedPatch.parentIdUpdate, mailboxSession)
- .andThen(applyNameUpdate(validatedPatch.nameUpdate,
mailboxSession))
- .apply(oldPath)
- if (!oldPath.equals(newPath)) {
- mailboxManager.renameMailbox(mailboxId,
- newPath,
- RenameOption.RENAME_SUBSCRIPTIONS,
- mailboxSession)
- }
- MailboxUpdateSuccess(mailboxId)
- } catch {
- case e: Exception => MailboxUpdateFailure(unparsedMailboxId, e,
Some(validatedPatch))
+ SMono.fromCallable[MailboxUpdateResult](() => {
+ try {
+ if (isASystemMailbox(mailbox) &&
!DefaultMailboxes.INBOX.equalsIgnoreCase(mailbox.getMailboxPath.getName)) {
+ throw SystemMailboxChangeException(mailboxId)
+ }
+ if
(validatedPatch.parentIdUpdate.flatMap(_.newId).contains(mailboxId)) {
+ throw LoopInMailboxGraphException(mailboxId)
+ }
+ val oldPath = mailbox.getMailboxPath
+ val newPath = applyParentIdUpdate(mailboxId,
validatedPatch.parentIdUpdate, mailboxSession, supportSharedMailbox)
+ .andThen(applyNameUpdate(validatedPatch.nameUpdate,
mailboxSession))
+ .apply(oldPath)
+ if (!oldPath.equals(newPath)) {
+ mailboxManager.renameMailbox(mailboxId,
+ newPath,
+ RenameOption.RENAME_SUBSCRIPTIONS,
+ mailboxSession)
}
- }).subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER)
- .flatMap(updateResult =>
createInboxIfNeeded(mailbox.getMailboxPath, mailboxSession)
- .`then`(SMono.just(updateResult))))
+ MailboxUpdateSuccess(mailboxId)
+ } catch {
+ case e: Exception => MailboxUpdateFailure(unparsedMailboxId, e,
Some(validatedPatch))
+ }
+ }).subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER)
+ .flatMap(updateResult => createInboxIfNeeded(mailbox.getMailboxPath,
mailboxSession)
+ .`then`(SMono.just(updateResult)))
} else {
SMono.just[MailboxUpdateResult](MailboxUpdateSuccess(mailboxId))
}
}
- private def applyParentIdUpdate(mailboxId: MailboxId, maybeParentIdUpdate:
Option[ParentIdUpdate], mailboxSession: MailboxSession): MailboxPath =>
MailboxPath = {
- maybeParentIdUpdate.map(parentIdUpdate => applyParentIdUpdate(mailboxId,
parentIdUpdate, mailboxSession))
+ private def applyParentIdUpdate(mailboxId: MailboxId, maybeParentIdUpdate:
Option[ParentIdUpdate],
+ mailboxSession: MailboxSession,
supportSharedMailbox: Boolean): MailboxPath => MailboxPath =
+ maybeParentIdUpdate.map(parentIdUpdate => applyParentIdUpdate(mailboxId,
parentIdUpdate, mailboxSession, supportSharedMailbox))
.getOrElse(x => x)
- }
private def applyNameUpdate(maybeNameUpdate: Option[NameUpdate],
mailboxSession: MailboxSession): MailboxPath => MailboxPath = {
originalPath => maybeNameUpdate.map(nameUpdate => {
@@ -213,7 +214,8 @@ class MailboxSetUpdatePerformer @Inject()(serializer:
MailboxSerializer,
}).getOrElse(originalPath)
}
- private def applyParentIdUpdate(mailboxId: MailboxId, parentIdUpdate:
ParentIdUpdate, mailboxSession: MailboxSession): MailboxPath => MailboxPath = {
+ private def applyParentIdUpdate(mailboxId: MailboxId, parentIdUpdate:
ParentIdUpdate,
+ mailboxSession: MailboxSession,
supportSharedMailbox: Boolean): MailboxPath => MailboxPath = {
originalPath => {
val currentName = originalPath.getName(mailboxSession.getPathDelimiter)
parentIdUpdate.newId
@@ -233,12 +235,17 @@ class MailboxSetUpdatePerformer @Inject()(serializer:
MailboxSerializer,
throw LoopInMailboxGraphException(mailboxId)
}
val parentPath = mailboxManager.getMailbox(id,
mailboxSession).getMailboxPath
+ if (!parentPath.belongsTo(mailboxSession) && !supportSharedMailbox)
throw new MailboxNotFoundException(id)
parentPath.child(currentName, mailboxSession.getPathDelimiter)
})
.getOrElse(MailboxPath.forUser(originalPath.getUser, currentName))
}
}
+ private def getMessageManager(supportSharedMailbox: Boolean, mailboxId:
MailboxId, mailboxSession: MailboxSession): SMono[MessageManager] =
+ SMono(mailboxManager.getMailboxReactive(mailboxId, mailboxSession))
+
.filterWhen(MailboxSetMethod.assertCapabilityIfSharedMailbox(mailboxSession,
mailboxId, supportSharedMailbox))
+
private def updateMailboxRights(mailboxId: MailboxId,
validatedPatch: ValidatedMailboxPatchObject,
mailboxSession: MailboxSession):
SMono[MailboxUpdateResult] = {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]