You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/03/25 01:41:04 UTC

[james-project] 01/02: JAMES-3087 Fix QueryParameterAccessTokenAuthenticationStrategy

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 9d599ad968013365661028bb02b4788ed19fbf41
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Mar 24 18:26:48 2020 +0700

    JAMES-3087 Fix QueryParameterAccessTokenAuthenticationStrategy
---
 .../integration/cucumber/DownloadStepdefs.java     | 17 ++++++++++++++
 .../resources/cucumber/DownloadEndpoint.feature    |  2 +-
 ...ParameterAccessTokenAuthenticationStrategy.java | 27 ++++++++++++++++++----
 3 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/DownloadStepdefs.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/DownloadStepdefs.java
index 961ada7..eb1e05f 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/DownloadStepdefs.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/DownloadStepdefs.java
@@ -194,6 +194,16 @@ public class DownloadStepdefs {
         downLoad(username, attachmentIdOrMessageId);
     }
 
+    @When("^\"([^\"]*)\" downloads \"([^\"]*)\" using query parameter strategy$")
+    public void downloadsUsingQueryParameter(String username, String blobId) throws Throwable {
+        String attachmentIdOrMessageId = Optional.ofNullable(blobIdByAttachmentId.get(blobId))
+            .orElse(Optional.ofNullable(inputToMessageId.get(blobId))
+                .map(MessageId::serialize)
+                .orElse(null));
+        URIBuilder uriBuilder = baseUri(mainStepdefs.jmapServer).setPath("/download/" + attachmentIdOrMessageId);
+        response = queryParameterDownloadRequest(uriBuilder, attachmentIdOrMessageId, username).execute().returnResponse();
+    }
+
     @When("^un-authenticated user downloads \"([^\"]*)\"$")
     public void downloadsUnAuthenticated(String blobId) throws Throwable {
         String attachmentIdOrMessageId = Optional.ofNullable(blobIdByAttachmentId.get(blobId))
@@ -232,6 +242,13 @@ public class DownloadStepdefs {
         return request;
     }
 
+    private Request queryParameterDownloadRequest(URIBuilder uriBuilder, String blobId, String username) throws URISyntaxException {
+        AccessToken accessToken = userStepdefs.authenticate(username);
+        AttachmentAccessTokenKey key = new AttachmentAccessTokenKey(username, blobId);
+        uriBuilder.addParameter("access_token", attachmentAccessTokens.get(key).serialize());
+        return Request.Get(uriBuilder.build());
+    }
+
     @When("^\"([^\"]*)\" is trusted for attachment \"([^\"]*)\"$")
     public void attachmentAccessTokenFor(String username, String attachmentId) throws Throwable {
         userStepdefs.connectUser(username);
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
index 2920b19..6270201 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
@@ -73,7 +73,7 @@ Feature: Download endpoint
   @BasicFeature
   Scenario: A user should have access to the download endpoint when an authentication token is valid
     Given "usera@domain.tld" is trusted for attachment "a1"
-    When "usera@domain.tld" downloads "a1"
+    When "usera@domain.tld" downloads "a1" using query parameter strategy
     Then the user should be authorized
 
   Scenario: An authenticated user should have access to the download endpoint
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/QueryParameterAccessTokenAuthenticationStrategy.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/QueryParameterAccessTokenAuthenticationStrategy.java
index 1aa6e5b..cc211e5 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/QueryParameterAccessTokenAuthenticationStrategy.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/QueryParameterAccessTokenAuthenticationStrategy.java
@@ -20,6 +20,8 @@ package org.apache.james.jmap.http;
 
 import static org.apache.james.jmap.http.DownloadRoutes.BLOB_ID_PATH_PARAM;
 
+import java.util.Optional;
+
 import javax.inject.Inject;
 
 import org.apache.james.core.Username;
@@ -31,6 +33,7 @@ import org.apache.james.mailbox.MailboxSession;
 
 import com.google.common.annotations.VisibleForTesting;
 
+import io.netty.handler.codec.http.QueryStringDecoder;
 import reactor.core.publisher.Mono;
 import reactor.netty.http.server.HttpServerRequest;
 
@@ -49,7 +52,7 @@ public class QueryParameterAccessTokenAuthenticationStrategy implements Authenti
 
     @Override
     public Mono<MailboxSession> createMailboxSession(HttpServerRequest httpRequest) {
-        return getAccessToken(httpRequest)
+        return Mono.justOrEmpty(getAccessToken(httpRequest))
             .filter(tokenManager::isValid)
             .map(AttachmentAccessToken::getUsername)
             .map(Username::of)
@@ -57,12 +60,26 @@ public class QueryParameterAccessTokenAuthenticationStrategy implements Authenti
             .switchIfEmpty(Mono.error(new UnauthorizedException()));
     }
 
-    private Mono<AttachmentAccessToken> getAccessToken(HttpServerRequest httpRequest) {
+    private Optional<AttachmentAccessToken> getAccessToken(HttpServerRequest httpRequest) {
         try {
-            return Mono.justOrEmpty(httpRequest.param(BLOB_ID_PATH_PARAM))
-                .map(blobId -> AttachmentAccessToken.from(httpRequest.param(AUTHENTICATION_PARAMETER), blobId));
+
+            return Optional.ofNullable(httpRequest.param(BLOB_ID_PATH_PARAM))
+                .flatMap(blobId -> queryParam(httpRequest, AUTHENTICATION_PARAMETER)
+                    .map(serializedAttachmentAccessToken -> AttachmentAccessToken.from(serializedAttachmentAccessToken, blobId)));
         } catch (IllegalArgumentException e) {
-            return Mono.empty();
+            return Optional.empty();
         }
     }
+
+    private Optional<String> queryParam(HttpServerRequest httpRequest, String parameterName) {
+        return queryParam(parameterName, httpRequest.uri());
+    }
+
+    private Optional<String> queryParam(String parameterName, String uri) {
+        return new QueryStringDecoder(uri)
+            .parameters()
+            .get(parameterName)
+            .stream()
+            .findFirst();
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org