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/12/23 03:51:23 UTC
[james-project] 09/10: JAMES-3464 Mailbox/get+set state properties
should respect specified SHARES capability
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 cac509bc99167f9587009609e4e1146664dc54c8
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Dec 21 15:18:06 2020 +0700
JAMES-3464 Mailbox/get+set state properties should respect specified SHARES capability
If the SHARE capability is specified by the client, the server can include state generated within
delegated mailboxes for Mailbox/get state and Mailbox/set oldState & newState properties.
If omitted we should filter these changes out and return the last change within a
personal mailbox.
---
.../change/CassandraMailboxChangeRepository.java | 5 ++
.../jmap/api/change/MailboxChangeRepository.java | 2 +
.../change/MemoryMailboxChangeRepository.java | 9 ++
.../change/MailboxChangeRepositoryContract.java | 68 +++++++++++++++
.../contract/MailboxGetMethodContract.scala | 97 +++++++++++++++++++++
.../contract/MailboxSetMethodContract.scala | 99 +++++++++++++++++++++-
.../james/jmap/method/MailboxGetMethod.scala | 16 +++-
.../james/jmap/method/MailboxSetMethod.scala | 15 +++-
8 files changed, 303 insertions(+), 8 deletions(-)
diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/change/CassandraMailboxChangeRepository.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/change/CassandraMailboxChangeRepository.java
index 72410b6..b17175a 100644
--- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/change/CassandraMailboxChangeRepository.java
+++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/change/CassandraMailboxChangeRepository.java
@@ -50,4 +50,9 @@ public class CassandraMailboxChangeRepository implements MailboxChangeRepository
public Mono<MailboxChange.State> getLatestState(AccountId accountId) {
return Mono.just(MailboxChange.State.INITIAL);
}
+
+ @Override
+ public Mono<MailboxChange.State> getLatestStateWithDelegation(AccountId accountId) {
+ return Mono.just(MailboxChange.State.INITIAL);
+ }
}
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/MailboxChangeRepository.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/MailboxChangeRepository.java
index 201e022..39779b6 100644
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/MailboxChangeRepository.java
+++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/change/MailboxChangeRepository.java
@@ -36,4 +36,6 @@ public interface MailboxChangeRepository {
Mono<MailboxChanges> getSinceStateWithDelegation(AccountId accountId, State state, Optional<Limit> maxChanges);
Mono<State> getLatestState(AccountId accountId);
+
+ Mono<State> getLatestStateWithDelegation(AccountId accountId);
}
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/change/MemoryMailboxChangeRepository.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/change/MemoryMailboxChangeRepository.java
index ab91994..44e5aee 100644
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/change/MemoryMailboxChangeRepository.java
+++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/memory/change/MemoryMailboxChangeRepository.java
@@ -103,6 +103,15 @@ public class MemoryMailboxChangeRepository implements MailboxChangeRepository {
@Override
public Mono<State> getLatestState(AccountId accountId) {
return Flux.fromIterable(mailboxChangeMap.get(accountId))
+ .filter(change -> !change.isDelegated())
+ .sort(Comparator.comparing(MailboxChange::getDate))
+ .map(MailboxChange::getState)
+ .last(State.INITIAL);
+ }
+
+ @Override
+ public Mono<State> getLatestStateWithDelegation(AccountId accountId) {
+ return Flux.fromIterable(mailboxChangeMap.get(accountId))
.sort(Comparator.comparing(MailboxChange::getDate))
.map(MailboxChange::getState)
.last(State.INITIAL);
diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/change/MailboxChangeRepositoryContract.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/change/MailboxChangeRepositoryContract.java
index 5a65347..922d0e9 100644
--- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/change/MailboxChangeRepositoryContract.java
+++ b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/change/MailboxChangeRepositoryContract.java
@@ -81,6 +81,74 @@ public interface MailboxChangeRepositoryContract {
}
@Test
+ default void getLatestStateShouldNotReturnDelegated() {
+ MailboxChangeRepository repository = mailboxChangeRepository();
+ State.Factory stateFactory = stateFactory();
+
+ MailboxChange change1 = MailboxChange.builder().accountId(ACCOUNT_ID).state(stateFactory.generate()).date(DATE.minusHours(2)).created(ImmutableList.of(TestId.of(2))).build();
+ MailboxChange change2 = MailboxChange.builder().accountId(ACCOUNT_ID).state(stateFactory.generate()).date(DATE.minusHours(1)).created(ImmutableList.of(TestId.of(3))).build();
+ MailboxChange change3 = MailboxChange.builder()
+ .accountId(ACCOUNT_ID)
+ .state(stateFactory.generate())
+ .date(DATE)
+ .created(ImmutableList.of(TestId.of(4)))
+ .delegated()
+ .build();
+ repository.save(change1).block();
+ repository.save(change2).block();
+ repository.save(change3).block();
+
+ assertThat(repository.getLatestState(ACCOUNT_ID).block())
+ .isEqualTo(change2.getState());
+ }
+
+ @Test
+ default void getLatestStateWithDelegationShouldReturnInitialWhenEmpty() {
+ MailboxChangeRepository repository = mailboxChangeRepository();
+
+ assertThat(repository.getLatestStateWithDelegation(ACCOUNT_ID).block())
+ .isEqualTo(State.INITIAL);
+ }
+
+ @Test
+ default void getLatestStateWithDelegationShouldReturnLastPersistedState() {
+ MailboxChangeRepository repository = mailboxChangeRepository();
+ State.Factory stateFactory = stateFactory();
+
+ MailboxChange change1 = MailboxChange.builder().accountId(ACCOUNT_ID).state(stateFactory.generate()).date(DATE.minusHours(2)).created(ImmutableList.of(TestId.of(2))).build();
+ MailboxChange change2 = MailboxChange.builder().accountId(ACCOUNT_ID).state(stateFactory.generate()).date(DATE.minusHours(1)).created(ImmutableList.of(TestId.of(3))).build();
+ MailboxChange change3 = MailboxChange.builder().accountId(ACCOUNT_ID).state(stateFactory.generate()).date(DATE).created(ImmutableList.of(TestId.of(4))).build();
+ repository.save(change1).block();
+ repository.save(change2).block();
+ repository.save(change3).block();
+
+ assertThat(repository.getLatestStateWithDelegation(ACCOUNT_ID).block())
+ .isEqualTo(change3.getState());
+ }
+
+ @Test
+ default void getLatestStateWithDelegationShouldReturnDelegated() {
+ MailboxChangeRepository repository = mailboxChangeRepository();
+ State.Factory stateFactory = stateFactory();
+
+ MailboxChange change1 = MailboxChange.builder().accountId(ACCOUNT_ID).state(stateFactory.generate()).date(DATE.minusHours(2)).created(ImmutableList.of(TestId.of(2))).build();
+ MailboxChange change2 = MailboxChange.builder().accountId(ACCOUNT_ID).state(stateFactory.generate()).date(DATE.minusHours(1)).created(ImmutableList.of(TestId.of(3))).build();
+ MailboxChange change3 = MailboxChange.builder()
+ .accountId(ACCOUNT_ID)
+ .state(stateFactory.generate())
+ .date(DATE)
+ .created(ImmutableList.of(TestId.of(4)))
+ .delegated()
+ .build();
+ repository.save(change1).block();
+ repository.save(change2).block();
+ repository.save(change3).block();
+
+ assertThat(repository.getLatestStateWithDelegation(ACCOUNT_ID).block())
+ .isEqualTo(change3.getState());
+ }
+
+ @Test
default void saveChangeShouldFailWhenNoAccountId() {
MailboxChangeRepository repository = mailboxChangeRepository();
State.Factory stateFactory = stateFactory();
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 dce8b7d..b26a148 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
@@ -1592,4 +1592,101 @@ trait MailboxGetMethodContract {
| "destroyed": []
|}""".stripMargin)
}
+
+ @Test
+ def stateShouldNotTakeIntoAccountDelegationWhenNoCapability(server: GuiceJamesServer): Unit = {
+ val state: String = `with`()
+ .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)
+ .post
+ .`then`()
+ .extract()
+ .jsonPath()
+ .get("methodResponses[0][1].state")
+
+ val sharedMailboxName = "AndreShared"
+ val andreMailboxPath = MailboxPath.forUser(ANDRE, sharedMailboxName)
+ 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"
+ | },
+ | "c1"]]
+ |}""".stripMargin)
+ .when
+ .post
+ .`then`
+ .statusCode(SC_OK)
+ .body(s"$ARGUMENTS.state", equalTo(state))
+ }
+
+ @Test
+ def stateShouldTakeIntoAccountDelegationWhenCapability(server: GuiceJamesServer): Unit = {
+ val state: String = `with`()
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(
+ s"""{
+ | "using": ["urn:ietf:params:jmap:core","urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares"],
+ | "methodCalls": [[
+ | "Mailbox/get",
+ | {
+ | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6"
+ | },
+ | "c1"]]
+ |}""".stripMargin)
+ .post
+ .`then`()
+ .extract()
+ .jsonPath()
+ .get("methodResponses[0][1].state")
+
+ val sharedMailboxName = "AndreShared"
+ val andreMailboxPath = MailboxPath.forUser(ANDRE, sharedMailboxName)
+ 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",
+ | "urn:apache:james:params:jmap:mail:shares"],
+ | "methodCalls": [[
+ | "Mailbox/get",
+ | {
+ | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6"
+ | },
+ | "c1"]]
+ |}""".stripMargin)
+ .when
+ .post
+ .`then`
+ .statusCode(SC_OK)
+ .body(s"$ARGUMENTS.state", not(equalTo(state)))
+ }
}
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 cc19ef6..3e034fd 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
@@ -35,6 +35,7 @@ import org.apache.james.jmap.core.State.INSTANCE
import org.apache.james.jmap.draft.MessageIdProbe
import org.apache.james.jmap.http.UserCredential
import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ANDRE, BOB, BOB_PASSWORD, CEDRIC, DAVID, DOMAIN, authScheme, baseRequestSpecBuilder}
+import org.apache.james.jmap.rfc8621.contract.MailboxGetMethodContract.ARGUMENTS
import org.apache.james.jmap.rfc8621.contract.tags.CategoryTags
import org.apache.james.mailbox.MessageManager.AppendCommand
import org.apache.james.mailbox.model.MailboxACL.{EntryKey, Right}
@@ -45,7 +46,7 @@ import org.apache.james.util.concurrency.ConcurrentTestRunner
import org.apache.james.utils.DataProbeImpl
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.{Assertions, SoftAssertions}
-import org.hamcrest.Matchers.{equalTo, hasSize}
+import org.hamcrest.Matchers.{equalTo, hasSize, not}
import org.junit.jupiter.api.{BeforeEach, Disabled, RepeatedTest, Tag, Test}
trait MailboxSetMethodContract {
@@ -7740,4 +7741,100 @@ trait MailboxSetMethodContract {
| "destroyed": []
|}""".stripMargin)
}
+
+ @Test
+ def stateShouldNotTakeIntoAccountDelegationWhenNoCapability(server: GuiceJamesServer): Unit = {
+ val state: String = `with`()
+ .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)
+ .post
+ .`then`()
+ .extract()
+ .jsonPath()
+ .get("methodResponses[0][1].state")
+
+ val sharedMailboxName = "AndreShared"
+ val andreMailboxPath = MailboxPath.forUser(ANDRE, sharedMailboxName)
+ 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/set",
+ | {
+ | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6"
+ | }, "c1"]]
+ |}""".stripMargin)
+ .when
+ .post
+ .`then`
+ .statusCode(SC_OK)
+ .body("methodResponses[0][1].oldState", equalTo(state))
+ }
+
+ @Test
+ def stateShouldTakeIntoAccountDelegationWhenCapability(server: GuiceJamesServer): Unit = {
+ val state: String = `with`()
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(
+ s"""{
+ | "using": ["urn:ietf:params:jmap:core","urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares"],
+ | "methodCalls": [[
+ | "Mailbox/get",
+ | {
+ | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6"
+ | },
+ | "c1"]]
+ |}""".stripMargin)
+ .post
+ .`then`()
+ .extract()
+ .jsonPath()
+ .get("methodResponses[0][1].state")
+
+ val sharedMailboxName = "AndreShared"
+ val andreMailboxPath = MailboxPath.forUser(ANDRE, sharedMailboxName)
+ 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",
+ | "urn:apache:james:params:jmap:mail:shares"],
+ | "methodCalls": [[
+ | "Mailbox/set",
+ | {
+ | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6"
+ | },
+ | "c1"]]
+ |}""".stripMargin)
+ .when
+ .post
+ .`then`
+ .statusCode(SC_OK)
+ .body("methodResponses[0][1].oldState", not(equalTo(state)))
+ }
}
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 9f2b735..dc7f123 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
@@ -23,9 +23,8 @@ import eu.timepit.refined.auto._
import javax.inject.Inject
import org.apache.james.jmap.api.change.MailboxChangeRepository
import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
-import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL}
+import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.State.INSTANCE
import org.apache.james.jmap.core.{AccountId, CapabilityIdentifier, ErrorCode, Invocation, Properties, State}
import org.apache.james.jmap.http.MailboxesProvisioner
import org.apache.james.jmap.json.{MailboxSerializer, ResponseSerializer}
@@ -81,8 +80,8 @@ class MailboxGetMethod @Inject() (serializer: MailboxSerializer,
(requestedProperties -- Mailbox.allProperties match {
case invalidProperties if invalidProperties.isEmpty() => getMailboxes(capabilities, request, mailboxSession)
.reduce(MailboxGetResults.empty(), MailboxGetResults.merge)
- .flatMap(mailboxes => SMono(mailboxChangeRepository.getLatestState(JavaAccountId.fromUsername(mailboxSession.getUser)))
- .map(state => mailboxes.asResponse(request.accountId, State.fromJava(state))))
+ .flatMap(mailboxes => retrieveState(capabilities, mailboxSession)
+ .map(state => mailboxes.asResponse(request.accountId, state)))
.map(mailboxGetResponse => Invocation(
methodName = methodName,
arguments = Arguments(serializer.serialize(mailboxGetResponse, requestedProperties, capabilities).as[JsObject]),
@@ -95,6 +94,15 @@ class MailboxGetMethod @Inject() (serializer: MailboxSerializer,
}
+ private def retrieveState(capabilities: Set[CapabilityIdentifier], mailboxSession: MailboxSession): SMono[State] =
+ if (capabilities.contains(JAMES_SHARES)) {
+ SMono(mailboxChangeRepository.getLatestStateWithDelegation(JavaAccountId.fromUsername(mailboxSession.getUser)))
+ .map(State.fromJava)
+ } else {
+ SMono(mailboxChangeRepository.getLatestState(JavaAccountId.fromUsername(mailboxSession.getUser)))
+ .map(State.fromJava)
+ }
+
override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, MailboxGetRequest] =
serializer.deserializeMailboxGetRequest(invocation.arguments.value) match {
case JsSuccess(mailboxGetRequest, _) => Right(mailboxGetRequest)
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 d4a8520..1bb2110 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
@@ -23,7 +23,7 @@ import eu.timepit.refined.auto._
import javax.inject.Inject
import org.apache.james.jmap.api.change.MailboxChangeRepository
import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
-import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL}
+import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
import org.apache.james.jmap.core.{Invocation, SetError, State}
import org.apache.james.jmap.json.{MailboxSerializer, ResponseSerializer}
@@ -55,11 +55,11 @@ class MailboxSetMethod @Inject()(serializer: MailboxSerializer,
override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JMAP_MAIL)
override def doProcess(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession, request: MailboxSetRequest): SMono[InvocationWithContext] = for {
- oldState <- SMono(mailboxChangeRepository.getLatestState(JavaAccountId.fromUsername(mailboxSession.getUser))).map(State.fromJava)
+ oldState <- retrieveState(capabilities, mailboxSession)
creationResults <- createPerformer.createMailboxes(mailboxSession, request, invocation.processingContext)
deletionResults <- deletePerformer.deleteMailboxes(mailboxSession, request)
updateResults <- updatePerformer.updateMailboxes(mailboxSession, request, capabilities)
- newState <- SMono(mailboxChangeRepository.getLatestState(JavaAccountId.fromUsername(mailboxSession.getUser))).map(State.fromJava)
+ newState <- retrieveState(capabilities, mailboxSession)
response = createResponse(capabilities, invocation.invocation, request, creationResults._1, deletionResults, updateResults, oldState, newState)
} yield InvocationWithContext(response, creationResults._2)
@@ -92,4 +92,13 @@ class MailboxSetMethod @Inject()(serializer: MailboxSerializer,
Arguments(serializer.serialize(response, capabilities).as[JsObject]),
invocation.methodCallId)
}
+
+ private def retrieveState(capabilities: Set[CapabilityIdentifier], mailboxSession: MailboxSession): SMono[State] =
+ if (capabilities.contains(JAMES_SHARES)) {
+ SMono(mailboxChangeRepository.getLatestStateWithDelegation(JavaAccountId.fromUsername(mailboxSession.getUser)))
+ .map(State.fromJava)
+ } else {
+ SMono(mailboxChangeRepository.getLatestState(JavaAccountId.fromUsername(mailboxSession.getUser)))
+ .map(State.fromJava)
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org