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
commit 2afc8e9f20e80ad77bbe60072f156203dd0953da Author: Benoit Tellier <btell...@linagora.com> AuthorDate: Fri Aug 14 11:53:22 2020 +0700 JAMES-3357 Mailbox/set create should handle isSubscribed --- .../contract/MailboxSetMethodContract.scala | 124 ++++++++++++++++++++- .../org/apache/james/jmap/json/Serializer.scala | 4 +- .../org/apache/james/jmap/mail/MailboxSet.scala | 2 +- .../james/jmap/method/MailboxSetMethod.scala | 28 +++-- 4 files changed, 143 insertions(+), 15 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 ac8b4a6..073b482 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 @@ -268,6 +268,128 @@ trait MailboxSetMethodContract { } @Test + def mailboxSetShouldSubscribeMailboxWhenRequired(server: GuiceJamesServer): Unit = { + val request = + """ + |{ + | "using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail" ], + | "methodCalls": [ + | [ + | "Mailbox/set", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "create": { + | "C42": { + | "name": "myMailbox", + | "isSubscribed": true + | } + | } + | }, + | "c1" + | ] + | ] + |} + |""".stripMargin + + `given` + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body(request) + .when + .post + .`then` + .log().ifValidationFails() + .statusCode(SC_OK) + .contentType(JSON) + .extract + .body + .asString + + Assertions.assertThat(server.getProbe(classOf[MailboxProbeImpl]) + .listSubscriptions(BOB.asString())).contains("myMailbox") + } + + @Test + def mailboxSetShouldNotSubscribeMailboxWhenRequired(server: GuiceJamesServer): Unit = { + val request= + """ + |{ + | "using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail" ], + | "methodCalls": [ + | [ + | "Mailbox/set", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "create": { + | "C42": { + | "name": "myMailbox", + | "isSubscribed": false + | } + | } + | }, + | "c1" + | ] + | ] + |} + |""".stripMargin + + `given` + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body(request) + .when + .post + .`then` + .log().ifValidationFails() + .statusCode(SC_OK) + .contentType(JSON) + .extract + .body + .asString + + Assertions.assertThat(server.getProbe(classOf[MailboxProbeImpl]) + .listSubscriptions(BOB.asString())).doesNotContain("myMailbox") + } + + @Test + def mailboxSetShouldSubscribeMailboxByDefault(server: GuiceJamesServer): Unit = { + val request= + """ + |{ + | "using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail" ], + | "methodCalls": [ + | [ + | "Mailbox/set", + | { + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "create": { + | "C42": { + | "name": "myMailbox" + | } + | } + | }, + | "c1" + | ] + | ] + |} + |""".stripMargin + + `given` + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body(request) + .when + .post + .`then` + .log().ifValidationFails() + .statusCode(SC_OK) + .contentType(JSON) + .extract + .body + .asString + + Assertions.assertThat(server.getProbe(classOf[MailboxProbeImpl]) + .listSubscriptions(BOB.asString())).contains("myMailbox") + } + + @Test def mailboxGetShouldAllowTheUseOfCreationIds(server: GuiceJamesServer): Unit = { val request = """ @@ -364,7 +486,7 @@ trait MailboxSetMethodContract { | "mayDelete": true, | "maySubmit": true | }, - | "isSubscribed": false + | "isSubscribed": true | }], | "notFound":[] | }, "c2"] diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala index e635254..ad8a19b 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala @@ -25,7 +25,6 @@ import java.net.URL import eu.timepit.refined._ import eu.timepit.refined.auto._ import javax.inject.Inject - import org.apache.james.core.{Domain, Username} import org.apache.james.jmap.mail.MailboxSetRequest.{MailboxCreationId, UnparsedMailboxId} import org.apache.james.jmap.mail.{DelegatedNamespace, Ids, IsSubscribed, Mailbox, MailboxCreationRequest, MailboxCreationResponse, MailboxGetRequest, MailboxGetResponse, MailboxNamespace, MailboxPatchObject, MailboxRights, MailboxSetError, MailboxSetRequest, MailboxSetResponse, MailboxUpdateResponse, MayAddItems, MayCreateChild, MayDelete, MayReadItems, MayRemoveItems, MayRename, MaySetKeywords, MaySetSeen, MaySubmit, NotFound, PersonalNamespace, Properties, Quota, QuotaId, QuotaRoot, Q [...] @@ -35,7 +34,6 @@ import org.apache.james.jmap.model.Invocation.{Arguments, MethodCallId, MethodNa import org.apache.james.jmap.model.{Account, Invocation, Session, _} import org.apache.james.mailbox.Role import org.apache.james.mailbox.model.{MailboxACL, MailboxId} - import play.api.libs.functional.syntax._ import play.api.libs.json._ @@ -159,7 +157,7 @@ class Serializer @Inject() (mailboxIdFactory: MailboxId.Factory) { private implicit val unreadEmailsWrites: Writes[UnreadEmails] = Json.valueWrites[UnreadEmails] private implicit val totalThreadsWrites: Writes[TotalThreads] = Json.valueWrites[TotalThreads] private implicit val unreadThreadsWrites: Writes[UnreadThreads] = Json.valueWrites[UnreadThreads] - private implicit val isSubscribedWrites: Writes[IsSubscribed] = Json.valueWrites[IsSubscribed] + private implicit val isSubscribedWrites: Format[IsSubscribed] = Json.valueFormat[IsSubscribed] private implicit val mayReadItemsWrites: Writes[MayReadItems] = Json.valueWrites[MayReadItems] private implicit val mayAddItemsWrites: Writes[MayAddItems] = Json.valueWrites[MayAddItems] diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxSet.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxSet.scala index 794a6a6..2d2c0b7 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxSet.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxSet.scala @@ -50,7 +50,7 @@ object MailboxSetRequest { } case class RemoveEmailsOnDestroy(value: Boolean) extends AnyVal -case class MailboxCreationRequest(name: MailboxName, parentId: Option[UnparsedMailboxId]) +case class MailboxCreationRequest(name: MailboxName, parentId: Option[UnparsedMailboxId], isSubscribed: Option[IsSubscribed]) case class MailboxPatchObject(value: Map[String, JsObject]) 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 24b7556..9aa20b4 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 @@ -30,7 +30,7 @@ import org.apache.james.jmap.model.{ClientId, Id, Invocation, ServerId, State} import org.apache.james.jmap.routes.ProcessingContext import org.apache.james.mailbox.exception.{InsufficientRightsException, MailboxExistsException, MailboxNameException, MailboxNotFoundException} import org.apache.james.mailbox.model.{FetchGroup, Mailbox, MailboxId, MailboxPath, MessageRange} -import org.apache.james.mailbox.{MailboxManager, MailboxSession} +import org.apache.james.mailbox.{MailboxManager, MailboxSession, SubscriptionManager} import org.apache.james.metrics.api.MetricFactory import org.reactivestreams.Publisher import play.api.libs.json._ @@ -113,6 +113,7 @@ case class DeletionResults(results: Seq[DeletionResult]) { class MailboxSetMethod @Inject()(serializer: Serializer, mailboxManager: MailboxManager, + subscriptionManager: SubscriptionManager, mailboxIdFactory: MailboxId.Factory, metricFactory: MetricFactory) extends Method { override val methodName: MethodName = MethodName("Mailbox/set") @@ -177,9 +178,15 @@ class MailboxSetMethod @Inject()(serializer: Serializer, jsObject: JsObject, processingContext: ProcessingContext): CreationResult = { parseCreate(jsObject) - .flatMap(mailboxCreationRequest => resolvePath(mailboxSession, mailboxCreationRequest, processingContext)) - .map(path => createMailbox(mailboxSession, mailboxCreationId, processingContext, path)) - .fold(e => CreationFailure(mailboxCreationId, e), r => r) + .flatMap(mailboxCreationRequest => resolvePath(mailboxSession, mailboxCreationRequest, processingContext) + .flatMap(path => createMailbox(mailboxSession = mailboxSession, + path = path, + isSubscribed = mailboxCreationRequest.isSubscribed.getOrElse(IsSubscribed(true))))) + .fold(e => CreationFailure(mailboxCreationId, e), + mailboxId => { + recordCreationIdInProcessingContext(mailboxCreationId, processingContext, mailboxId) + CreationSuccess(mailboxCreationId, mailboxId) + }) } private def parseCreate(jsObject: JsObject): Either[MailboxCreationParseException, MailboxCreationRequest] = @@ -197,16 +204,17 @@ class MailboxSetMethod @Inject()(serializer: Serializer, } private def createMailbox(mailboxSession: MailboxSession, - mailboxCreationId: MailboxCreationId, - processingContext: ProcessingContext, - path: MailboxPath): CreationResult = { + path: MailboxPath, + isSubscribed: IsSubscribed): Either[Exception, MailboxId] = { try { //can safely do a get as the Optional is empty only if the mailbox name is empty which is forbidden by the type constraint on MailboxName val mailboxId = mailboxManager.createMailbox(path, mailboxSession).get() - recordCreationIdInProcessingContext(mailboxCreationId, processingContext, mailboxId) - CreationSuccess(mailboxCreationId, mailboxId) + if (isSubscribed.value) { + subscriptionManager.subscribe(mailboxSession, path.getName) + } + Right(mailboxId) } catch { - case error: Exception => CreationFailure(mailboxCreationId, error) + case error: Exception => Left(error) } } --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org