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 6867c94624466b4ed217be3d267b60456ad9fad7 Author: Raphael Ouazana <[email protected]> AuthorDate: Thu Jul 23 17:13:29 2020 +0200 JAMES-2892 use the same default capabilities everywhere --- .../org/apache/james/jmap/json/Serializer.scala | 12 +++- .../org/apache/james/jmap/model/Capabilities.scala | 13 ++++- .../org/apache/james/jmap/model/Capability.scala | 18 +++++- .../apache/james/jmap/routes/JMAPApiRoutes.scala | 2 +- .../apache/james/jmap/http/SessionRoutesTest.scala | 68 +++++++++++++++++++++- .../james/jmap/json/SessionSerializationTest.scala | 6 +- 6 files changed, 106 insertions(+), 13 deletions(-) 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 d9e234a..614c6fa 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 @@ -93,9 +93,13 @@ class Serializer @Inject() (mailboxIdFactory: MailboxId.Factory) { private implicit val urlWrites: Writes[URL] = url => JsString(url.toString) private implicit val coreCapabilityWrites: Writes[CoreCapabilityProperties] = Json.writes[CoreCapabilityProperties] private implicit val mailCapabilityWrites: Writes[MailCapabilityProperties] = Json.writes[MailCapabilityProperties] + private implicit val quotaCapabilityWrites: Writes[QuotaCapabilityProperties] = OWrites[QuotaCapabilityProperties](_ => Json.obj()) + private implicit val sharesCapabilityWrites: Writes[SharesCapabilityProperties] = OWrites[SharesCapabilityProperties](_ => Json.obj()) private implicit def setCapabilityWrites(implicit corePropertiesWriter: Writes[CoreCapabilityProperties], - mailCapabilityWrites: Writes[MailCapabilityProperties]): Writes[Set[_ <: Capability]] = + mailCapabilityWrites: Writes[MailCapabilityProperties], + quotaCapabilityWrites: Writes[QuotaCapabilityProperties], + sharesCapabilityWrites: Writes[SharesCapabilityProperties]): Writes[Set[_ <: Capability]] = (set: Set[_ <: Capability]) => { set.foldLeft(JsObject.empty)((jsObject, capability) => { capability match { @@ -103,12 +107,16 @@ class Serializer @Inject() (mailboxIdFactory: MailboxId.Factory) { jsObject.+(capability.identifier.value, corePropertiesWriter.writes(capability.properties))) case capability: MailCapability => ( jsObject.+(capability.identifier.value, mailCapabilityWrites.writes(capability.properties))) + case capability: QuotaCapability => ( + jsObject.+(capability.identifier.value, quotaCapabilityWrites.writes(capability.properties))) + case capability: SharesCapability => ( + jsObject.+(capability.identifier.value, sharesCapabilityWrites.writes(capability.properties))) case _ => jsObject } }) } - private implicit val capabilitiesWrites: Writes[Capabilities] = capabilities => setCapabilityWrites.writes(Set(capabilities.coreCapability, capabilities.mailCapability)) + private implicit val capabilitiesWrites: Writes[Capabilities] = capabilities => setCapabilityWrites.writes(capabilities.toSet) private implicit val accountIdWrites: Format[AccountId] = Json.valueFormat[AccountId] private implicit def identifierMapWrite[Any](implicit idWriter: Writes[AccountId]): Writes[Map[CapabilityIdentifier, Any]] = diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capabilities.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capabilities.scala index ac0a7d4..9fe910f 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capabilities.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capabilities.scala @@ -19,6 +19,7 @@ package org.apache.james.jmap.model import eu.timepit.refined.auto._ +import org.apache.james.jmap.model.CapabilityIdentifier.CapabilityIdentifier object DefaultCapabilities { val CORE_CAPABILITY = CoreCapability( @@ -43,9 +44,15 @@ object DefaultCapabilities { ) ) - val SUPPORTED = Capabilities(CORE_CAPABILITY, MAIL_CAPABILITY) + val QUOTA_CAPABILITY = QuotaCapability() + + val SHARES_CAPABILITY = SharesCapability() + + val SUPPORTED = Capabilities(CORE_CAPABILITY, MAIL_CAPABILITY, QUOTA_CAPABILITY, SHARES_CAPABILITY) } -case class Capabilities(coreCapability: CoreCapability, mailCapability: MailCapability) { - def toSet : Set[Capability] = Set(coreCapability, mailCapability) +case class Capabilities(capabilities: Capability*) { + def toSet : Set[Capability] = capabilities.toSet + + def ids : Set[CapabilityIdentifier] = toSet.map(_.identifier()) } diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capability.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capability.scala index 8eaaefb..1ade76e 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capability.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/Capability.scala @@ -23,7 +23,7 @@ import eu.timepit.refined.api.Refined import eu.timepit.refined.auto._ import eu.timepit.refined.collection.NonEmpty import eu.timepit.refined.string.Uri -import org.apache.james.jmap.model.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL} +import org.apache.james.jmap.model.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL, JAMES_QUOTA, JAMES_SHARES} import org.apache.james.jmap.model.CoreCapabilityProperties.CollationAlgorithm import org.apache.james.jmap.model.MailCapability.EmailQuerySortOption import org.apache.james.jmap.model.UnsignedInt.UnsignedInt @@ -34,8 +34,6 @@ object CapabilityIdentifier { val JMAP_MAIL: CapabilityIdentifier = "urn:ietf:params:jmap:mail" val JAMES_QUOTA: CapabilityIdentifier = "urn:apache:james:params:jmap:mail:quota" val JAMES_SHARES: CapabilityIdentifier = "urn:apache:james:params:jmap:mail:shares" - - val SUPPORTED_CAPABILITIES: Set[CapabilityIdentifier] = Set(JMAP_CORE, JMAP_MAIL, JAMES_QUOTA, JAMES_SHARES) } sealed trait CapabilityProperties @@ -91,3 +89,17 @@ final case class MailCapabilityProperties(maxMailboxesPerEmail: MaxMailboxesPerE mayCreateTopLevelMailbox: MayCreateTopLevelMailbox) extends CapabilityProperties { } +final case class QuotaCapabilityProperties() extends CapabilityProperties { +} + +final case class QuotaCapability(properties: QuotaCapabilityProperties = QuotaCapabilityProperties(), + identifier: CapabilityIdentifier = JAMES_QUOTA) extends Capability { +} + +final case class SharesCapabilityProperties() extends CapabilityProperties { +} + +final case class SharesCapability(properties: SharesCapabilityProperties = SharesCapabilityProperties(), + identifier: CapabilityIdentifier = JAMES_SHARES) extends Capability { +} + diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala index 45dfda5..320c540 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala @@ -104,7 +104,7 @@ class JMAPApiRoutes (val authenticator: Authenticator, private def process(requestObject: RequestObject, httpServerResponse: HttpServerResponse, mailboxSession: MailboxSession): SMono[Void] = { - val unsupportedCapabilities = requestObject.using.toSet -- CapabilityIdentifier.SUPPORTED_CAPABILITIES + val unsupportedCapabilities = requestObject.using.toSet -- DefaultCapabilities.SUPPORTED.ids if (unsupportedCapabilities.nonEmpty) { SMono.raiseError(UnsupportedCapabilitiesException(unsupportedCapabilities)) diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala index 0501f8b..47e89ee 100644 --- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala +++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala @@ -31,7 +31,6 @@ import org.apache.http.HttpStatus import org.apache.james.core.Username import org.apache.james.jmap._ import org.apache.james.jmap.http.SessionRoutesTest.{BOB, TEST_CONFIGURATION} -import org.apache.james.jmap.json.Fixture.expected_session_object_json import org.apache.james.jmap.json.Serializer import org.apache.james.mailbox.MailboxSession import org.apache.james.mailbox.model.TestId @@ -101,7 +100,72 @@ class SessionRoutesTest extends AnyFlatSpec with BeforeAndAfter with Matchers { .thenReturn .getBody .asString() + val expectedJson = """{ + | "capabilities" : { + | "urn:ietf:params:jmap:core" : { + | "maxSizeUpload" : 10000000, + | "maxConcurrentUpload" : 4, + | "maxSizeRequest" : 10000000, + | "maxConcurrentRequests" : 4, + | "maxCallsInRequest" : 16, + | "maxObjectsInGet" : 500, + | "maxObjectsInSet" : 500, + | "collationAlgorithms" : [ "i;unicode-casemap" ] + | }, + | "urn:ietf:params:jmap:mail" : { + | "maxMailboxesPerEmail" : 10000000, + | "maxMailboxDepth" : null, + | "maxSizeMailboxName" : 200, + | "maxSizeAttachmentsPerEmail" : 20000000, + | "emailQuerySortOptions" : [ "receivedAt", "cc", "from", "to", "subject", "size", "sentAt", "hasKeyword", "uid", "Id" ], + | "mayCreateTopLevelMailbox" : true + | }, + | "urn:apache:james:params:jmap:mail:quota": {}, + | "urn:apache:james:params:jmap:mail:shares": {} + | }, + | "accounts" : { + | "0fe275bf13ff761407c17f64b1dfae2f4b3186feea223d7267b79f873a105401" : { + | "name" : "[email protected]", + | "isPersonal" : true, + | "isReadOnly" : false, + | "accountCapabilities" : { + | "urn:ietf:params:jmap:core" : { + | "maxSizeUpload" : 10000000, + | "maxConcurrentUpload" : 4, + | "maxSizeRequest" : 10000000, + | "maxConcurrentRequests" : 4, + | "maxCallsInRequest" : 16, + | "maxObjectsInGet" : 500, + | "maxObjectsInSet" : 500, + | "collationAlgorithms" : [ "i;unicode-casemap" ] + | }, + | "urn:ietf:params:jmap:mail" : { + | "maxMailboxesPerEmail" : 10000000, + | "maxMailboxDepth" : null, + | "maxSizeMailboxName" : 200, + | "maxSizeAttachmentsPerEmail" : 20000000, + | "emailQuerySortOptions" : [ "receivedAt", "cc", "from", "to", "subject", "size", "sentAt", "hasKeyword", "uid", "Id" ], + | "mayCreateTopLevelMailbox" : true + | }, + | "urn:apache:james:params:jmap:mail:quota": {}, + | "urn:apache:james:params:jmap:mail:shares": {} + | } + | } + | }, + | "primaryAccounts" : { + | "urn:ietf:params:jmap:core" : "0fe275bf13ff761407c17f64b1dfae2f4b3186feea223d7267b79f873a105401", + | "urn:ietf:params:jmap:mail" : "0fe275bf13ff761407c17f64b1dfae2f4b3186feea223d7267b79f873a105401", + | "urn:apache:james:params:jmap:mail:quota": "0fe275bf13ff761407c17f64b1dfae2f4b3186feea223d7267b79f873a105401", + | "urn:apache:james:params:jmap:mail:shares": "0fe275bf13ff761407c17f64b1dfae2f4b3186feea223d7267b79f873a105401" + | }, + | "username" : "[email protected]", + | "apiUrl" : "http://this-url-is-hardcoded.org/jmap", + | "downloadUrl" : "http://this-url-is-hardcoded.org/download", + | "uploadUrl" : "http://this-url-is-hardcoded.org/upload", + | "eventSourceUrl" : "http://this-url-is-hardcoded.org/eventSource", + | "state" : "000001" + |}""".stripMargin - Json.parse(sessionJson) should equal(expected_session_object_json) + Json.parse(sessionJson) should equal(Json.parse(expectedJson)) } } diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala index 5a418d8..6daaa45 100644 --- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala +++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala @@ -79,7 +79,7 @@ object SessionSerializationTest { emailQuerySortOptions = EMAIL_QUERY_SORT_OPTIONS, mayCreateTopLevelMailbox = MAY_CREATE_TOP_LEVEL_MAILBOX)) - private val CAPABILITIES = Capabilities(CORE_CAPABILITY, MAIL_CAPABILITY) + private val CAPABILITIES = Capabilities(CORE_CAPABILITY, MAIL_CAPABILITY, QuotaCapability(), SharesCapability()) private val IS_PERSONAL : IsPersonal = IsPersonal(true) private val IS_NOT_PERSONAL : IsPersonal = IsPersonal(false) @@ -148,7 +148,9 @@ class SessionSerializationTest extends AnyWordSpec with Matchers { | "maxSizeAttachmentsPerEmail": 890099, | "emailQuerySortOptions": ["size"], | "mayCreateTopLevelMailbox": true - | } + | }, + | "urn:apache:james:params:jmap:mail:quota":{}, + | "urn:apache:james:params:jmap:mail:shares":{} | }, | "accounts": { | "807a5306ccb4527af7790a0f9b48a776514bdbfba064e355461a76bcffbf2c90": { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
