You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/12/13 01:24:44 UTC
[james-project] branch master updated (19de56e -> 6fbe9f3)
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git.
from 19de56e JAMES-3683 log4j 2.14.1 -> 2.15.0 to address CVE-2021-44228 (#793)
new f5ac1a6 JAMES-3680 Clean code JmapRfc8621Configuration
new 6fbe9f3 JAMES-3680 Allow Jmap session endpoint return dynamic prefix in response
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../docs/modules/ROOT/pages/configure/jmap.adoc | 25 +++--
.../org/apache/james/jmap/draft/JMAPModule.java | 3 +-
.../src/test/resources/jmap.properties | 3 +-
.../rfc8621/contract/SessionRoutesContract.scala | 37 +++++++
.../src/test/resources/jmap.properties | 3 +-
.../org/apache/james/jmap/core/Capabilities.scala | 3 +-
.../james/jmap/core/JmapRfc8621Configuration.scala | 56 +++++-----
.../apache/james/jmap/routes/SessionRoutes.scala | 35 ++++--
.../apache/james/jmap/routes/SessionSupplier.scala | 53 +++++++--
.../jmap/core/JmapRfc8621ConfigurationTest.scala | 59 ----------
.../jmap/core/JmapUrlEndpointResolverTest.scala | 123 +++++++++++++++++++++
.../james/jmap/routes/SessionRoutesTest.scala | 10 +-
src/site/xdoc/server/config-jmap.xml | 8 ++
13 files changed, 296 insertions(+), 122 deletions(-)
delete mode 100644 server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapRfc8621ConfigurationTest.scala
create mode 100644 server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapUrlEndpointResolverTest.scala
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 02/02: JAMES-3680 Allow Jmap session endpoint return dynamic prefix in response
Posted by bt...@apache.org.
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 6fbe9f3b2a92af03c721f3ecdb9333db6b0f7a0b
Author: Tung Van TRAN <vt...@linagora.com>
AuthorDate: Mon Dec 6 17:59:55 2021 +0700
JAMES-3680 Allow Jmap session endpoint return dynamic prefix in response
---
.../docs/modules/ROOT/pages/configure/jmap.adoc | 25 +++--
.../org/apache/james/jmap/draft/JMAPModule.java | 3 +-
.../src/test/resources/jmap.properties | 3 +-
.../rfc8621/contract/SessionRoutesContract.scala | 37 +++++++
.../src/test/resources/jmap.properties | 3 +-
.../org/apache/james/jmap/core/Capabilities.scala | 3 +-
.../james/jmap/core/JmapRfc8621Configuration.scala | 22 ++--
.../apache/james/jmap/routes/SessionRoutes.scala | 33 ++++--
.../apache/james/jmap/routes/SessionSupplier.scala | 53 +++++++--
.../jmap/core/JmapRfc8621ConfigurationTest.scala | 59 ----------
.../jmap/core/JmapUrlEndpointResolverTest.scala | 123 +++++++++++++++++++++
src/site/xdoc/server/config-jmap.xml | 8 ++
12 files changed, 269 insertions(+), 103 deletions(-)
diff --git a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/jmap.adoc b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/jmap.adoc
index b3e29fd..35da385 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/jmap.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/jmap.adoc
@@ -31,36 +31,39 @@ This should not be the same keystore than the ones used by TLS based protocols.
Defaults to an empty list.
| url.prefix
-| Optional. Configuration urlPrefix for JMAP routes.
-| Default value: http://localhost.
+| Optional. Configuration urlPrefix for JMAP routes. Default value: http://localhost.
| websocket.url.prefix
-| Optional. URL for JMAP WebSocket route.
-| Default value: ws://localhost
+| Optional. URL for JMAP WebSocket route. Default value: ws://localhost
| email.send.max.size
| Optional. Configuration max size for message created in both JMAP Draft amd RFC-8621.
-| Default value: None. Supported units are B (bytes) K (KB) M (MB) G (GB).
+Default value: None. Supported units are B (bytes) K (KB) M (MB) G (GB).
| upload.max.size
| Optional. Configuration max size Upload in new JMAP-RFC-8621.
-| Default value: 30M. Supported units are B (bytes) K (KB) M (MB) G (GB).
+Default value: 30M. Supported units are B (bytes) K (KB) M (MB) G (GB).
| view.email.query.enabled
-| Optional boolean. Defaults to false.
-| Should simple Email/query be resolved against a Cassandra projection, or should we resolve them against ElasticSearch?
+| Optional boolean. Defaults to false. Should simple Email/query be resolved against a Cassandra projection, or should we resolve them against ElasticSearch?
This enables a higher resilience, but the projection needs to be correctly populated.
| user.provisioning.enabled
-| Optional boolean. Defaults to true.
-| Governs whether authenticated users that do not exist locally should be created in the users repository.
+| Optional boolean. Defaults to true. Governs whether authenticated users that do not exist locally should be created in the users repository.
| jmap.version.default
| Optional string. Defaults to draft. Allowed values: draft, rfc-8621.
-| Which version of the JMAP protocol should be served when none supplied in the Accept header.
+Which version of the JMAP protocol should be served when none supplied in the Accept header.
Defaults to draft for legacy reasons (avoid breaking changes) but setting the value to
rfc-8621 allow compatibility with other third party apps.
+| dynamic.jmap.prefix.resolution.enabled
+| Optional boolean. Defaults to false. Supported Jmap session endpoint returns dynamic prefix in response.
+When its config is true, and the HTTP request to Jmap session endpoint has a `X-JMAP-PREFIX` header with the value `http://new-domain/prefix`,
+then `apiUrl, downloadUrl, uploadUrl, eventSourceUrl, webSocketUrl` in response will be changed with a new prefix. Example: The `apiUrl` will be "http://new-domain/prefix/jmap".
+If the HTTP request to Jmap session endpoint has the `X-JMAP-WEBSOCKET-PREFIX` header with the value `ws://new-domain/prefix`,
+then `capabilities."urn:ietf:params:jmap:websocket".url` in response will be "ws://new-domain/prefix/jmap/ws".
+
|===
== Wire tapping
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
index dd8bc82..6c9c532 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
@@ -46,6 +46,7 @@ import org.apache.james.jmap.draft.utils.JsoupHtmlTextExtractor;
import org.apache.james.jmap.event.PropagateLookupRightListener;
import org.apache.james.jmap.mailet.filter.JMAPFiltering;
import org.apache.james.jmap.rfc8621.RFC8621MethodsModule;
+import org.apache.james.jmap.routes.JmapUrlEndpointResolver;
import org.apache.james.jwt.JwtConfiguration;
import org.apache.james.jwt.JwtTokenVerifier;
import org.apache.james.lifecycle.api.StartUpCheck;
@@ -166,7 +167,7 @@ public class JMAPModule extends AbstractModule {
@ProvidesIntoSet
Capability webSocketCapability(JmapRfc8621Configuration configuration) {
- return DefaultCapabilities.webSocketCapability(configuration.webSocketUrl());
+ return DefaultCapabilities.webSocketCapability(JmapUrlEndpointResolver.from(configuration).webSocketUrl());
}
@Provides
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/resources/jmap.properties b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/resources/jmap.properties
index e04d1d8..e91d491 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/resources/jmap.properties
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/resources/jmap.properties
@@ -1,4 +1,5 @@
# Configuration urlPrefix for JMAP routes.
url.prefix=http://domain.com
websocket.url.prefix=ws://domain.com
-upload.max.size=20M
\ No newline at end of file
+upload.max.size=20M
+dynamic.jmap.prefix.resolution.enabled=true
\ No newline at end of file
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/SessionRoutesContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/SessionRoutesContract.scala
index 0a22aab..e38189e 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/SessionRoutesContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/SessionRoutesContract.scala
@@ -36,6 +36,7 @@ import org.apache.james.jmap.rfc8621.contract.Fixture._
import org.apache.james.jmap.rfc8621.contract.SessionRoutesContract.{EXPECTED_BASE_PATH, expected_session_object}
import org.apache.james.jmap.rfc8621.contract.tags.CategoryTags
import org.apache.james.utils.DataProbeImpl
+import org.hamcrest.Matchers
import org.junit.jupiter.api.{BeforeEach, Tag, Test}
object SessionRoutesContract {
@@ -171,4 +172,40 @@ trait SessionRoutesContract {
assertThatJson(sessionJson).isEqualTo(expected_session_object)
}
+
+ @Test
+ def getResponseShouldReturnUrlEndpointContainJmapPrefixWhenAssignHeaderAndConfigurationProvided(): Unit = {
+ `given`()
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .header("X-JMAP-PREFIX", "http://new-domain.tld/prefix")
+ .header("X-JMAP-WEBSOCKET-PREFIX", "ws://new-domain.tld/prefix")
+ .when()
+ .get("/session")
+ .`then`
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .body("apiUrl", Matchers.is("http://new-domain.tld/prefix/jmap"))
+ .body("downloadUrl", Matchers.is("http://new-domain.tld/prefix/download/{accountId}/{blobId}?type={type}&name={name}"))
+ .body("uploadUrl", Matchers.is("http://new-domain.tld/prefix/upload/{accountId}"))
+ .body("eventSourceUrl", Matchers.is("http://new-domain.tld/prefix/eventSource?types={types}&closeAfter={closeafter}&ping={ping}"))
+ .body("capabilities.\"urn:ietf:params:jmap:websocket\".url", Matchers.is("ws://new-domain.tld/prefix/jmap/ws"))
+ }
+
+ @Test
+ def getResponseShouldReturnUrlEndpointNOTContainJmapPrefixWhenAssignInvalidHeader(): Unit = {
+ val sessionJson: String = `given`()
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .header("X-JMAP-PREFIX", "new@domain")
+ .when()
+ .get("/session")
+ .`then`
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .extract()
+ .body()
+ .asString()
+
+ assertThatJson(sessionJson).isEqualTo(expected_session_object)
+ }
+
}
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/resources/jmap.properties b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/resources/jmap.properties
index c9a4dff..519703e 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/resources/jmap.properties
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/resources/jmap.properties
@@ -3,4 +3,5 @@ url.prefix=http://domain.com
websocket.url.prefix=ws://domain.com
upload.max.size=20M
webpush.maxTimeoutSeconds=10
-webpush.maxConnections=10
\ No newline at end of file
+webpush.maxConnections=10
+dynamic.jmap.prefix.resolution.enabled=true
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capabilities.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capabilities.scala
index 6a899c0..229e917 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capabilities.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capabilities.scala
@@ -22,6 +22,7 @@ import java.net.URI
import eu.timepit.refined.auto._
import org.apache.james.jmap.core.CapabilityIdentifier.CapabilityIdentifier
+import org.apache.james.jmap.routes.JmapUrlEndpointResolver
object DefaultCapabilities {
def coreCapability(maxUploadSize: MaxSizeUpload) = CoreCapability(
@@ -59,7 +60,7 @@ object DefaultCapabilities {
SHARES_CAPABILITY,
VACATION_RESPONSE_CAPABILITY,
SUBMISSION_CAPABILITY,
- webSocketCapability(configuration.webSocketUrl))
+ webSocketCapability(JmapUrlEndpointResolver.from(configuration).webSocketUrl))
}
object Capabilities {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/JmapRfc8621Configuration.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/JmapRfc8621Configuration.scala
index 75fd931..a197e35 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/JmapRfc8621Configuration.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/JmapRfc8621Configuration.scala
@@ -19,7 +19,6 @@
package org.apache.james.jmap.core
-import java.net.{URI, URL}
import java.util.Optional
import org.apache.commons.configuration2.Configuration
@@ -35,6 +34,7 @@ object JmapConfigProperties {
val WEBSOCKET_URL_PREFIX_PROPERTY: String = "websocket.url.prefix"
val WEB_PUSH_MAX_TIMEOUT_SECONDS_PROPERTY: String = "webpush.maxTimeoutSeconds"
val WEB_PUSH_MAX_CONNECTIONS_PROPERTY: String = "webpush.maxConnections"
+ val DYNAMIC_JMAP_PREFIX_RESOLUTION_ENABLED_PROPERTY: String = "dynamic.jmap.prefix.resolution.enabled"
}
object JmapRfc8621Configuration {
@@ -43,32 +43,30 @@ object JmapRfc8621Configuration {
val WEBSOCKET_URL_PREFIX_DEFAULT: String = "ws://localhost"
val UPLOAD_LIMIT_DEFAULT: MaxSizeUpload = MaxSizeUpload.of(Size.of(30L, Size.Unit.M)).get
- val LOCALHOST_CONFIGURATION: JmapRfc8621Configuration = JmapRfc8621Configuration(URL_PREFIX_DEFAULT, WEBSOCKET_URL_PREFIX_DEFAULT, UPLOAD_LIMIT_DEFAULT)
+ val LOCALHOST_CONFIGURATION: JmapRfc8621Configuration = JmapRfc8621Configuration(
+ urlPrefixString = URL_PREFIX_DEFAULT,
+ websocketPrefixString = WEBSOCKET_URL_PREFIX_DEFAULT,
+ maxUploadSize = UPLOAD_LIMIT_DEFAULT)
-
- def from(configuration: Configuration): JmapRfc8621Configuration = {
+ def from(configuration: Configuration): JmapRfc8621Configuration =
JmapRfc8621Configuration(
urlPrefixString = Option(configuration.getString(URL_PREFIX_PROPERTY)).getOrElse(URL_PREFIX_DEFAULT),
websocketPrefixString = Option(configuration.getString(WEBSOCKET_URL_PREFIX_PROPERTY)).getOrElse(WEBSOCKET_URL_PREFIX_DEFAULT),
+ dynamicJmapPrefixResolutionEnabled = configuration.getBoolean(DYNAMIC_JMAP_PREFIX_RESOLUTION_ENABLED_PROPERTY, false),
maxUploadSize = Option(configuration.getString(UPLOAD_LIMIT_PROPERTY, null))
.map(Size.parse)
.map(MaxSizeUpload.of(_).get)
.getOrElse(UPLOAD_LIMIT_DEFAULT),
maxTimeoutSeconds = Optional.ofNullable(configuration.getInteger(WEB_PUSH_MAX_TIMEOUT_SECONDS_PROPERTY, null)).map(Integer2int).toScala,
maxConnections = Optional.ofNullable(configuration.getInteger(WEB_PUSH_MAX_CONNECTIONS_PROPERTY, null)).map(Integer2int).toScala)
- }
}
-case class JmapRfc8621Configuration(urlPrefixString: String, websocketPrefixString: String,
+case class JmapRfc8621Configuration(urlPrefixString: String,
+ websocketPrefixString: String,
+ dynamicJmapPrefixResolutionEnabled: Boolean = false,
maxUploadSize: MaxSizeUpload = UPLOAD_LIMIT_DEFAULT,
maxTimeoutSeconds: Option[Int] = None,
maxConnections: Option[Int] = None) {
- val urlPrefix: URL = new URL(urlPrefixString)
- val apiUrl: URL = new URL(s"$urlPrefixString/jmap")
- val downloadUrl: URL = new URL(urlPrefixString + "/download/{accountId}/{blobId}?type={type}&name={name}")
- val uploadUrl: URL = new URL(s"$urlPrefixString/upload/{accountId}")
- val eventSourceUrl: URL = new URL(s"$urlPrefixString/eventSource?types={types}&closeAfter={closeafter}&ping={ping}")
- val webSocketUrl: URI = new URI(s"$websocketPrefixString/jmap/ws")
val webPushConfiguration: PushClientConfiguration = PushClientConfiguration(
maxTimeoutSeconds = maxTimeoutSeconds,
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionRoutes.scala
index 26af361..01d1424 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionRoutes.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionRoutes.scala
@@ -1,4 +1,4 @@
-/** **************************************************************
+/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
@@ -6,19 +6,20 @@
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
- * ***************************************************************/
+ ****************************************************************/
package org.apache.james.jmap.routes
+import java.net.{URI, URL}
import java.nio.charset.StandardCharsets
import java.util.stream.Stream
@@ -33,19 +34,23 @@ import org.apache.james.jmap.exceptions.UnauthorizedException
import org.apache.james.jmap.http.Authenticator
import org.apache.james.jmap.http.rfc8621.InjectionKeys
import org.apache.james.jmap.json.ResponseSerializer
-import org.apache.james.jmap.routes.SessionRoutes.{JMAP_SESSION, LOGGER, WELL_KNOWN_JMAP}
+import org.apache.james.jmap.routes.SessionRoutes.{JMAP_PREFIX_HEADER, JMAP_SESSION, JMAP_WEBSOCKET_PREFIX_HEADER, LOGGER, WELL_KNOWN_JMAP}
import org.apache.james.jmap.{Endpoint, JMAPRoute, JMAPRoutes}
-import org.slf4j.LoggerFactory
+import org.slf4j.{Logger, LoggerFactory}
import play.api.libs.json.Json
import reactor.core.publisher.Mono
import reactor.core.scala.publisher.SMono
import reactor.core.scheduler.Schedulers
-import reactor.netty.http.server.HttpServerResponse
+import reactor.netty.http.server.{HttpServerRequest, HttpServerResponse}
+
+import scala.util.Try
object SessionRoutes {
private val JMAP_SESSION: String = "/jmap/session"
private val WELL_KNOWN_JMAP: String = "/.well-known/jmap"
- private val LOGGER = LoggerFactory.getLogger(classOf[SessionRoutes])
+ private val LOGGER: Logger = LoggerFactory.getLogger(classOf[SessionRoutes])
+ private val JMAP_PREFIX_HEADER: String = "X-JMAP-PREFIX"
+ private val JMAP_WEBSOCKET_PREFIX_HEADER: String = "X-JMAP-WEBSOCKET-PREFIX"
}
class SessionRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticator: Authenticator,
@@ -55,7 +60,7 @@ class SessionRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticator:
(request, response) => SMono.fromPublisher(authenticator.authenticate(request))
.map(_.getUser)
.handle[Session] {
- case (username, sink) => sessionSupplier.generate(username)
+ case (username, sink) => sessionSupplier.generate(username, extractJMAPPrefix(request), extractJMAPWebSocketPrefix(request))
.fold(sink.error, session => sink.next(session))
}
.flatMap(session => sendRespond(session, response))
@@ -63,6 +68,14 @@ class SessionRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticator:
.subscribeOn(Schedulers.elastic())
.asJava()
+ private def extractJMAPPrefix(request: HttpServerRequest): Option[URL] =
+ Option(request.requestHeaders().get(JMAP_PREFIX_HEADER))
+ .flatMap(value => Try(new URL(value)).toOption)
+
+ private def extractJMAPWebSocketPrefix(request: HttpServerRequest): Option[URI] =
+ Option(request.requestHeaders().get(JMAP_WEBSOCKET_PREFIX_HEADER))
+ .flatMap(value => Try(new URI(value)).toOption)
+
private val redirectToSession: JMAPRoute.Action = JMAPRoutes.redirectTo(JMAP_SESSION)
override def routes: Stream[JMAPRoute] =
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionSupplier.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionSupplier.scala
index ba96092..d9d4b8e 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionSupplier.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionSupplier.scala
@@ -19,10 +19,12 @@
package org.apache.james.jmap.routes
+import java.net.{URI, URL}
+
import javax.inject.Inject
import org.apache.james.core.Username
import org.apache.james.jmap.core.CapabilityIdentifier.CapabilityIdentifier
-import org.apache.james.jmap.core.{Account, AccountId, Capabilities, Capability, IsPersonal, IsReadOnly, JmapRfc8621Configuration, Session}
+import org.apache.james.jmap.core.{Account, AccountId, Capabilities, Capability, IsPersonal, IsReadOnly, JmapRfc8621Configuration, Session, WebSocketCapability}
import scala.jdk.CollectionConverters._
@@ -37,17 +39,25 @@ class SessionSupplier(val configuration: JmapRfc8621Configuration, defaultCapabi
.toOption
.getOrElse(false)
- def generate(username: Username): Either[IllegalArgumentException, Session] =
+ def generate(username: Username, urlPrefix: Option[URL] = None, webSocketUriPrefix: Option[URI] = None): Either[IllegalArgumentException, Session] = {
+ val urlEndpointResolver: JmapUrlEndpointResolver = new JmapUrlEndpointResolver(configuration, urlPrefix, webSocketUriPrefix)
+ val capabilities: Set[Capability] = defaultCapabilities
+ .map {
+ case websocketCapability: WebSocketCapability =>
+ websocketCapability.copy(properties = websocketCapability.properties.copy(url = urlEndpointResolver.webSocketUrl))
+ case another => another
+ }
accounts(username)
.map(account => Session(
- Capabilities(defaultCapabilities),
+ Capabilities(capabilities),
List(account),
primaryAccounts(account.accountId),
username,
- apiUrl = configuration.apiUrl,
- downloadUrl = configuration.downloadUrl,
- uploadUrl = configuration.uploadUrl,
- eventSourceUrl = configuration.eventSourceUrl))
+ apiUrl = urlEndpointResolver.apiUrl,
+ downloadUrl = urlEndpointResolver.downloadUrl,
+ uploadUrl = urlEndpointResolver.uploadUrl,
+ eventSourceUrl = urlEndpointResolver.eventSourceUrl))
+ }
private def accounts(username: Username): Either[IllegalArgumentException, Account] =
Account.from(username, IsPersonal(true), IsReadOnly(false), defaultCapabilities)
@@ -57,3 +67,32 @@ class SessionSupplier(val configuration: JmapRfc8621Configuration, defaultCapabi
.map(capability => (capability.identifier(), accountId))
.toMap
}
+
+object JmapUrlEndpointResolver {
+ def from(configuration: JmapRfc8621Configuration): JmapUrlEndpointResolver = new JmapUrlEndpointResolver(configuration)
+}
+
+class JmapUrlEndpointResolver(val configuration: JmapRfc8621Configuration,
+ urlPrefixRequest: Option[URL] = None,
+ uriWebSocketPrefixRequest: Option[URI] = None) {
+
+ val urlPrefix: String = Some(configuration.dynamicJmapPrefixResolutionEnabled)
+ .filter(enabled => enabled)
+ .flatMap(_ => urlPrefixRequest.map(_.toString))
+ .getOrElse(configuration.urlPrefixString)
+
+ val uriWebSocketPrefix: String = Some(configuration.dynamicJmapPrefixResolutionEnabled)
+ .filter(enabled => enabled)
+ .flatMap(_ => uriWebSocketPrefixRequest.map(_.toString))
+ .getOrElse(configuration.websocketPrefixString)
+
+ val apiUrl: URL = new URL(s"$urlPrefix/jmap")
+
+ val downloadUrl: URL = new URL(s"$urlPrefix/download/{accountId}/{blobId}?type={type}&name={name}")
+
+ val uploadUrl: URL = new URL(s"$urlPrefix/upload/{accountId}")
+
+ val webSocketUrl: URI = new URI(s"$uriWebSocketPrefix/jmap/ws")
+
+ val eventSourceUrl: URL = new URL(s"$urlPrefix/eventSource?types={types}&closeAfter={closeafter}&ping={ping}")
+}
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapRfc8621ConfigurationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapRfc8621ConfigurationTest.scala
deleted file mode 100644
index 0a26f14..0000000
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapRfc8621ConfigurationTest.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.jmap.core
-
-import java.net.URL
-
-import org.apache.commons.configuration2.{Configuration, PropertiesConfiguration}
-import org.apache.james.jmap.core.JmapConfigProperties.URL_PREFIX_PROPERTY
-import org.apache.james.jmap.core.JmapRfc8621ConfigurationTest.{emptyConfiguration, providedConfiguration}
-import org.scalatest.matchers.must.Matchers
-import org.scalatest.wordspec.AnyWordSpec
-
-object JmapRfc8621ConfigurationTest {
- val emptyConfiguration: Configuration = new PropertiesConfiguration()
- def providedConfiguration(): Configuration = {
- val configuration: Configuration = new PropertiesConfiguration()
- configuration.addProperty(URL_PREFIX_PROPERTY, "http://random-domain.com")
- configuration
- }
-}
-
-class JmapRfc8621ConfigurationTest extends AnyWordSpec with Matchers {
- "JmapRfc8621ConfigurationTest" should {
- "succeed to configuration urlPrefix when provided" in {
- val jmapRfc8621Configuration: JmapRfc8621Configuration = JmapRfc8621Configuration.from(providedConfiguration())
-
- jmapRfc8621Configuration.apiUrl must be(new URL("http://random-domain.com/jmap"))
- jmapRfc8621Configuration.downloadUrl must be(new URL("http://random-domain.com/download/{accountId}/{blobId}?type={type}&name={name}"))
- jmapRfc8621Configuration.uploadUrl must be(new URL("http://random-domain.com/upload/{accountId}"))
- jmapRfc8621Configuration.eventSourceUrl must be(new URL("http://random-domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}"))
- }
-
- "load default config for urlPrefix when no configuration provided" in {
- val jmapRfc8621Configuration: JmapRfc8621Configuration = JmapRfc8621Configuration.from(emptyConfiguration)
-
- jmapRfc8621Configuration.apiUrl must be(new URL("http://localhost/jmap"))
- jmapRfc8621Configuration.downloadUrl must be(new URL("http://localhost/download/{accountId}/{blobId}?type={type}&name={name}"))
- jmapRfc8621Configuration.uploadUrl must be(new URL("http://localhost/upload/{accountId}"))
- jmapRfc8621Configuration.eventSourceUrl must be(new URL("http://localhost/eventSource?types={types}&closeAfter={closeafter}&ping={ping}"))
- }
- }
-}
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapUrlEndpointResolverTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapUrlEndpointResolverTest.scala
new file mode 100644
index 0000000..40aa9e3
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapUrlEndpointResolverTest.scala
@@ -0,0 +1,123 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.jmap.core
+
+import java.net.{URI, URL}
+
+import org.apache.commons.configuration2.{Configuration, PropertiesConfiguration}
+import org.apache.james.jmap.core.JmapConfigProperties.{DYNAMIC_JMAP_PREFIX_RESOLUTION_ENABLED_PROPERTY, URL_PREFIX_PROPERTY, WEBSOCKET_URL_PREFIX_PROPERTY}
+import org.apache.james.jmap.core.JmapUrlEndpointResolverTest.{emptyConfiguration, providedConfiguration}
+import org.apache.james.jmap.routes.JmapUrlEndpointResolver
+import org.scalatest.matchers.must.Matchers
+import org.scalatest.wordspec.AnyWordSpec
+
+object JmapUrlEndpointResolverTest {
+ val emptyConfiguration: Configuration = new PropertiesConfiguration()
+ def providedConfiguration(): Configuration = {
+ val configuration: Configuration = new PropertiesConfiguration()
+ configuration.addProperty(URL_PREFIX_PROPERTY, "http://random-domain.com")
+ configuration.addProperty(WEBSOCKET_URL_PREFIX_PROPERTY, "ws://random-domain.com")
+ configuration
+ }
+}
+
+class JmapUrlEndpointResolverTest extends AnyWordSpec with Matchers {
+ "JmapUrlEndpointResolverTest" should {
+ "succeed to configuration urlPrefix when provided" in {
+ val jmapRfc8621Configuration: JmapRfc8621Configuration = JmapRfc8621Configuration.from(providedConfiguration())
+ val testee : JmapUrlEndpointResolver= new JmapUrlEndpointResolver(jmapRfc8621Configuration)
+
+ testee.apiUrl must be(new URL("http://random-domain.com/jmap"))
+ testee.downloadUrl must be(new URL("http://random-domain.com/download/{accountId}/{blobId}?type={type}&name={name}"))
+ testee.uploadUrl must be(new URL("http://random-domain.com/upload/{accountId}"))
+ testee.eventSourceUrl must be(new URL("http://random-domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}"))
+ testee.webSocketUrl must be(new URI("ws://random-domain.com/jmap/ws"))
+ }
+
+ "load default config for urlPrefix when no configuration provided" in {
+ val jmapRfc8621Configuration: JmapRfc8621Configuration = JmapRfc8621Configuration.from(emptyConfiguration)
+ val testee : JmapUrlEndpointResolver= new JmapUrlEndpointResolver(jmapRfc8621Configuration)
+
+ testee.apiUrl must be(new URL("http://localhost/jmap"))
+ testee.downloadUrl must be(new URL("http://localhost/download/{accountId}/{blobId}?type={type}&name={name}"))
+ testee.uploadUrl must be(new URL("http://localhost/upload/{accountId}"))
+ testee.eventSourceUrl must be(new URL("http://localhost/eventSource?types={types}&closeAfter={closeafter}&ping={ping}"))
+ testee.webSocketUrl must be(new URI("ws://localhost/jmap/ws"))
+ }
+
+ "dynamic jmap prefix should be set when has prefix request and configuration provided is true" in {
+ val configuration: Configuration = providedConfiguration()
+ configuration.addProperty(DYNAMIC_JMAP_PREFIX_RESOLUTION_ENABLED_PROPERTY, true)
+ val jmapRfc8621Configuration: JmapRfc8621Configuration = JmapRfc8621Configuration.from(configuration)
+ val testee : JmapUrlEndpointResolver= new JmapUrlEndpointResolver(jmapRfc8621Configuration,
+ Some(new URL("http://dynamic.tld/prefix")),
+ Some(new URI("ws://dynamic.tld/prefix")))
+
+ testee.apiUrl must be(new URL("http://dynamic.tld/prefix/jmap"))
+ testee.downloadUrl must be(new URL("http://dynamic.tld/prefix/download/{accountId}/{blobId}?type={type}&name={name}"))
+ testee.uploadUrl must be(new URL("http://dynamic.tld/prefix/upload/{accountId}"))
+ testee.eventSourceUrl must be(new URL("http://dynamic.tld/prefix/eventSource?types={types}&closeAfter={closeafter}&ping={ping}"))
+ testee.webSocketUrl must be(new URI("ws://dynamic.tld/prefix/jmap/ws"))
+ }
+
+ "dynamic jmap prefix should NOT be set when has prefix request and configuration provided is false" in {
+ val configuration: Configuration = providedConfiguration()
+ configuration.addProperty(DYNAMIC_JMAP_PREFIX_RESOLUTION_ENABLED_PROPERTY, false)
+ val jmapRfc8621Configuration: JmapRfc8621Configuration = JmapRfc8621Configuration.from(configuration)
+ val testee : JmapUrlEndpointResolver= new JmapUrlEndpointResolver(jmapRfc8621Configuration,
+ Some(new URL("http://dynamic.tld/prefix")),
+ Some(new URI("ws://dynamic.tld/prefix")))
+
+ testee.apiUrl must be(new URL("http://random-domain.com/jmap"))
+ testee.downloadUrl must be(new URL("http://random-domain.com/download/{accountId}/{blobId}?type={type}&name={name}"))
+ testee.uploadUrl must be(new URL("http://random-domain.com/upload/{accountId}"))
+ testee.eventSourceUrl must be(new URL("http://random-domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}"))
+ testee.webSocketUrl must be(new URI("ws://random-domain.com/jmap/ws"))
+ }
+
+ "dynamic jmap prefix should NOT be set when has prefix request and no configuration provided" in {
+ val configuration: Configuration = providedConfiguration()
+ val jmapRfc8621Configuration: JmapRfc8621Configuration = JmapRfc8621Configuration.from(configuration)
+ val testee : JmapUrlEndpointResolver= new JmapUrlEndpointResolver(jmapRfc8621Configuration,
+ Some(new URL("http://dynamic.tld/prefix")),
+ Some(new URI("ws://dynamic.tld/prefix")))
+
+ testee.apiUrl must be(new URL("http://random-domain.com/jmap"))
+ testee.downloadUrl must be(new URL("http://random-domain.com/download/{accountId}/{blobId}?type={type}&name={name}"))
+ testee.uploadUrl must be(new URL("http://random-domain.com/upload/{accountId}"))
+ testee.eventSourceUrl must be(new URL("http://random-domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}"))
+ testee.webSocketUrl must be(new URI("ws://random-domain.com/jmap/ws"))
+ }
+
+ "dynamic jmap prefix should NOT be set when has not prefix request" in {
+ val configuration: Configuration = providedConfiguration()
+ configuration.addProperty(DYNAMIC_JMAP_PREFIX_RESOLUTION_ENABLED_PROPERTY, true)
+
+ val jmapRfc8621Configuration: JmapRfc8621Configuration = JmapRfc8621Configuration.from(configuration)
+ val testee : JmapUrlEndpointResolver= new JmapUrlEndpointResolver(jmapRfc8621Configuration, None, None)
+
+ testee.apiUrl must be(new URL("http://random-domain.com/jmap"))
+ testee.downloadUrl must be(new URL("http://random-domain.com/download/{accountId}/{blobId}?type={type}&name={name}"))
+ testee.uploadUrl must be(new URL("http://random-domain.com/upload/{accountId}"))
+ testee.eventSourceUrl must be(new URL("http://random-domain.com/eventSource?types={types}&closeAfter={closeafter}&ping={ping}"))
+ testee.webSocketUrl must be(new URI("ws://random-domain.com/jmap/ws"))
+ }
+ }
+}
diff --git a/src/site/xdoc/server/config-jmap.xml b/src/site/xdoc/server/config-jmap.xml
index df5d11d..4553bc1 100644
--- a/src/site/xdoc/server/config-jmap.xml
+++ b/src/site/xdoc/server/config-jmap.xml
@@ -89,6 +89,14 @@
<dd>Which version of the JMAP protocol should be served when none supplied in the Accept header.
Defaults to draft for legacy reasons (avoid breaking changes) but setting the value to
rfc-8621 allow compatibility with other third party apps.</dd>
+
+ <dt><strong>dynamic.jmap.prefix.resolution.enabled</strong></dt>
+ <dd>Optional boolean. Defaults to false. Supported Jmap session endpoint returns dynamic prefix in response.
+ When its config is true, and the HTTP request to Jmap session endpoint has a `X-JMAP-PREFIX` header with the value `http://new-domain/prefix`,
+ then `apiUrl, downloadUrl, uploadUrl, eventSourceUrl, webSocketUrl` in response will be changed with a new prefix. Example: The `apiUrl` will be "http://new-domain/prefix/jmap".
+ If the HTTP request to Jmap session endpoint has the `X-JMAP-WEBSOCKET-PREFIX` header with the value `ws://new-domain/prefix`,
+ then `capabilities."urn:ietf:params:jmap:websocket".url` in response will be "ws://new-domain/prefix/jmap/ws".
+ </dd>
</dl>
</subsection>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org
[james-project] 01/02: JAMES-3680 Clean code JmapRfc8621Configuration
Posted by bt...@apache.org.
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 f5ac1a635551cba872481bc1be8540d39d37ae36
Author: Tung Van TRAN <vt...@linagora.com>
AuthorDate: Mon Dec 6 16:21:52 2021 +0700
JAMES-3680 Clean code JmapRfc8621Configuration
---
.../james/jmap/core/JmapRfc8621Configuration.scala | 38 +++++++++++++---------
.../apache/james/jmap/routes/SessionRoutes.scala | 2 +-
.../jmap/core/JmapRfc8621ConfigurationTest.scala | 4 +--
.../james/jmap/routes/SessionRoutesTest.scala | 10 +++---
4 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/JmapRfc8621Configuration.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/JmapRfc8621Configuration.scala
index 9d925ce..75fd931 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/JmapRfc8621Configuration.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/JmapRfc8621Configuration.scala
@@ -23,36 +23,44 @@ import java.net.{URI, URL}
import java.util.Optional
import org.apache.commons.configuration2.Configuration
-import org.apache.james.jmap.core.JmapRfc8621Configuration.UPLOAD_LIMIT_30_MB
+import org.apache.james.jmap.core.JmapRfc8621Configuration.UPLOAD_LIMIT_DEFAULT
import org.apache.james.jmap.pushsubscription.PushClientConfiguration
import org.apache.james.util.Size
import scala.jdk.OptionConverters._
+object JmapConfigProperties {
+ val UPLOAD_LIMIT_PROPERTY: String = "upload.max.size"
+ val URL_PREFIX_PROPERTY: String = "url.prefix"
+ val WEBSOCKET_URL_PREFIX_PROPERTY: String = "websocket.url.prefix"
+ val WEB_PUSH_MAX_TIMEOUT_SECONDS_PROPERTY: String = "webpush.maxTimeoutSeconds"
+ val WEB_PUSH_MAX_CONNECTIONS_PROPERTY: String = "webpush.maxConnections"
+}
+
object JmapRfc8621Configuration {
- val LOCALHOST_URL_PREFIX: String = "http://localhost"
- val LOCALHOST_WEBSOCKET_URL_PREFIX: String = "ws://localhost"
- val UPLOAD_LIMIT_30_MB: MaxSizeUpload = MaxSizeUpload.of(Size.of(30L, Size.Unit.M)).get
- val LOCALHOST_CONFIGURATION: JmapRfc8621Configuration = JmapRfc8621Configuration(LOCALHOST_URL_PREFIX, LOCALHOST_WEBSOCKET_URL_PREFIX, UPLOAD_LIMIT_30_MB)
- val URL_PREFIX_PROPERTIES: String = "url.prefix"
- val WEBSOCKET_URL_PREFIX_PROPERTIES: String = "websocket.url.prefix"
- val UPLOAD_LIMIT_PROPERTIES: String = "upload.max.size"
+ import JmapConfigProperties._
+ val URL_PREFIX_DEFAULT: String = "http://localhost"
+ val WEBSOCKET_URL_PREFIX_DEFAULT: String = "ws://localhost"
+ val UPLOAD_LIMIT_DEFAULT: MaxSizeUpload = MaxSizeUpload.of(Size.of(30L, Size.Unit.M)).get
+
+ val LOCALHOST_CONFIGURATION: JmapRfc8621Configuration = JmapRfc8621Configuration(URL_PREFIX_DEFAULT, WEBSOCKET_URL_PREFIX_DEFAULT, UPLOAD_LIMIT_DEFAULT)
+
def from(configuration: Configuration): JmapRfc8621Configuration = {
JmapRfc8621Configuration(
- urlPrefixString = Option(configuration.getString(URL_PREFIX_PROPERTIES)).getOrElse(LOCALHOST_URL_PREFIX),
- websocketPrefixString = Option(configuration.getString(WEBSOCKET_URL_PREFIX_PROPERTIES)).getOrElse(LOCALHOST_WEBSOCKET_URL_PREFIX),
- maxUploadSize = Option(configuration.getString(UPLOAD_LIMIT_PROPERTIES, null))
+ urlPrefixString = Option(configuration.getString(URL_PREFIX_PROPERTY)).getOrElse(URL_PREFIX_DEFAULT),
+ websocketPrefixString = Option(configuration.getString(WEBSOCKET_URL_PREFIX_PROPERTY)).getOrElse(WEBSOCKET_URL_PREFIX_DEFAULT),
+ maxUploadSize = Option(configuration.getString(UPLOAD_LIMIT_PROPERTY, null))
.map(Size.parse)
.map(MaxSizeUpload.of(_).get)
- .getOrElse(UPLOAD_LIMIT_30_MB),
- maxTimeoutSeconds = Optional.ofNullable(configuration.getInteger("webpush.maxTimeoutSeconds", null)).map(Integer2int).toScala,
- maxConnections = Optional.ofNullable(configuration.getInteger("webpush.maxConnections", null)).map(Integer2int).toScala)
+ .getOrElse(UPLOAD_LIMIT_DEFAULT),
+ maxTimeoutSeconds = Optional.ofNullable(configuration.getInteger(WEB_PUSH_MAX_TIMEOUT_SECONDS_PROPERTY, null)).map(Integer2int).toScala,
+ maxConnections = Optional.ofNullable(configuration.getInteger(WEB_PUSH_MAX_CONNECTIONS_PROPERTY, null)).map(Integer2int).toScala)
}
}
case class JmapRfc8621Configuration(urlPrefixString: String, websocketPrefixString: String,
- maxUploadSize: MaxSizeUpload = UPLOAD_LIMIT_30_MB,
+ maxUploadSize: MaxSizeUpload = UPLOAD_LIMIT_DEFAULT,
maxTimeoutSeconds: Option[Int] = None,
maxConnections: Option[Int] = None) {
val urlPrefix: URL = new URL(urlPrefixString)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionRoutes.scala
index 6d1ad8c..26af361 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionRoutes.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionRoutes.scala
@@ -84,7 +84,7 @@ class SessionRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticator:
.action(CORS_CONTROL)
.noCorsHeaders)
- private def sendRespond(session: Session, resp: HttpServerResponse) =
+ private def sendRespond(session: Session, resp: HttpServerResponse): SMono[Void] =
SMono.fromCallable(() => Json.stringify(ResponseSerializer.serialize(session)))
.map(_.getBytes(StandardCharsets.UTF_8))
.flatMap(bytes => SMono(resp.header(CONTENT_TYPE, JSON_CONTENT_TYPE_UTF8)
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapRfc8621ConfigurationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapRfc8621ConfigurationTest.scala
index 8bc3c64..0a26f14 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapRfc8621ConfigurationTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/core/JmapRfc8621ConfigurationTest.scala
@@ -22,7 +22,7 @@ package org.apache.james.jmap.core
import java.net.URL
import org.apache.commons.configuration2.{Configuration, PropertiesConfiguration}
-import org.apache.james.jmap.core.JmapRfc8621Configuration.URL_PREFIX_PROPERTIES
+import org.apache.james.jmap.core.JmapConfigProperties.URL_PREFIX_PROPERTY
import org.apache.james.jmap.core.JmapRfc8621ConfigurationTest.{emptyConfiguration, providedConfiguration}
import org.scalatest.matchers.must.Matchers
import org.scalatest.wordspec.AnyWordSpec
@@ -31,7 +31,7 @@ object JmapRfc8621ConfigurationTest {
val emptyConfiguration: Configuration = new PropertiesConfiguration()
def providedConfiguration(): Configuration = {
val configuration: Configuration = new PropertiesConfiguration()
- configuration.addProperty(URL_PREFIX_PROPERTIES, "http://random-domain.com")
+ configuration.addProperty(URL_PREFIX_PROPERTY, "http://random-domain.com")
configuration
}
}
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/SessionRoutesTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/SessionRoutesTest.scala
index c4833a7..1162fdc 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/SessionRoutesTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/SessionRoutesTest.scala
@@ -30,7 +30,7 @@ import io.restassured.http.ContentType
import net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson
import org.apache.http.HttpStatus
import org.apache.james.core.Username
-import org.apache.james.jmap.core.JmapRfc8621Configuration.LOCALHOST_URL_PREFIX
+import org.apache.james.jmap.core.JmapRfc8621Configuration.URL_PREFIX_DEFAULT
import org.apache.james.jmap.core.UuidState.INSTANCE
import org.apache.james.jmap.core.{DefaultCapabilities, JmapRfc8621Configuration}
import org.apache.james.jmap.http.Authenticator
@@ -200,10 +200,10 @@ class SessionRoutesTest extends AnyFlatSpec with BeforeAndAfter with Matchers {
| "urn:ietf:params:jmap:vacationresponse": "0fe275bf13ff761407c17f64b1dfae2f4b3186feea223d7267b79f873a105401"
| },
| "username" : "bob@james.org",
- | "apiUrl" : "$LOCALHOST_URL_PREFIX/jmap",
- | "downloadUrl" : "$LOCALHOST_URL_PREFIX/$downloadPath",
- | "uploadUrl" : "$LOCALHOST_URL_PREFIX/upload/{accountId}",
- | "eventSourceUrl" : "$LOCALHOST_URL_PREFIX/eventSource?types={types}&closeAfter={closeafter}&ping={ping}",
+ | "apiUrl" : "$URL_PREFIX_DEFAULT/jmap",
+ | "downloadUrl" : "$URL_PREFIX_DEFAULT/$downloadPath",
+ | "uploadUrl" : "$URL_PREFIX_DEFAULT/upload/{accountId}",
+ | "eventSourceUrl" : "$URL_PREFIX_DEFAULT/eventSource?types={types}&closeAfter={closeafter}&ping={ping}",
| "state" : "${INSTANCE.value}"
|}""".stripMargin
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org