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 ad...@apache.org on 2016/07/08 07:55:21 UTC
[1/4] james-project git commit: JAMES-1784 Authentication strategy
should be responsible of extracting the authentication part from the request
Repository: james-project
Updated Branches:
refs/heads/master d59881815 -> 85aeb1e45
JAMES-1784 Authentication strategy should be responsible of extracting the authentication part from the request
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/3c7cc854
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/3c7cc854
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/3c7cc854
Branch: refs/heads/master
Commit: 3c7cc854c42acc897d51828b590399320de32681
Parents: d598818
Author: Antoine Duprat <ad...@linagora.com>
Authored: Fri Jul 1 14:22:56 2016 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Jul 8 09:53:56 2016 +0200
----------------------------------------------------------------------
.../org/apache/james/jmap/JMAPCommonModule.java | 2 +
.../jmap/AccessTokenAuthenticationStrategy.java | 15 +++--
.../apache/james/jmap/AuthenticationFilter.java | 18 ++---
.../james/jmap/AuthenticationStrategy.java | 6 +-
.../james/jmap/JWTAuthenticationStrategy.java | 14 ++--
.../utils/HeadersAuthenticationExtractor.java | 41 ++++++++++++
.../AccessTokenAuthenticationStrategyTest.java | 54 ++++++++++++---
.../james/jmap/AuthenticationFilterTest.java | 5 +-
.../jmap/JWTAuthenticationStrategyTest.java | 54 +++++++++++----
.../HeadersAuthenticationExtractorTest.java | 69 ++++++++++++++++++++
10 files changed, 225 insertions(+), 53 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java b/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java
index 049f3b3..0d5362f 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java
@@ -34,6 +34,7 @@ import org.apache.james.jmap.model.MessageFactory;
import org.apache.james.jmap.model.MessagePreviewGenerator;
import org.apache.james.jmap.send.MailFactory;
import org.apache.james.jmap.send.MailSpool;
+import org.apache.james.jmap.utils.HeadersAuthenticationExtractor;
import org.apache.james.util.date.DefaultZonedDateTimeProvider;
import org.apache.james.util.date.ZonedDateTimeProvider;
import org.apache.mailet.base.AutomaticallySentMailDetector;
@@ -60,6 +61,7 @@ public class JMAPCommonModule extends AbstractModule {
bind(AutomaticallySentMailDetectorImpl.class).in(Scopes.SINGLETON);
bind(MessageFactory.class).in(Scopes.SINGLETON);
bind(MessagePreviewGenerator.class).in(Scopes.SINGLETON);
+ bind(HeadersAuthenticationExtractor.class).in(Scopes.SINGLETON);
bind(SignatureHandler.class).to(JamesSignatureHandler.class);
bind(ZonedDateTimeProvider.class).to(DefaultZonedDateTimeProvider.class);
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java
index 62043b5..d190ebd 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java
@@ -19,15 +19,16 @@
package org.apache.james.jmap;
import java.util.Optional;
-import java.util.stream.Stream;
import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
import org.apache.james.jmap.api.AccessTokenManager;
import org.apache.james.jmap.api.access.AccessToken;
import org.apache.james.jmap.api.access.exceptions.NotAnAccessTokenException;
import org.apache.james.jmap.exceptions.MailboxSessionCreationException;
import org.apache.james.jmap.exceptions.NoValidAuthHeaderException;
+import org.apache.james.jmap.utils.HeadersAuthenticationExtractor;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.exception.MailboxException;
@@ -42,18 +43,20 @@ public class AccessTokenAuthenticationStrategy implements AuthenticationStrategy
private final AccessTokenManager accessTokenManager;
private final MailboxManager mailboxManager;
+ private final HeadersAuthenticationExtractor authenticationExtractor;
@Inject
@VisibleForTesting
- AccessTokenAuthenticationStrategy(AccessTokenManager accessTokenManager, MailboxManager mailboxManager) {
+ AccessTokenAuthenticationStrategy(AccessTokenManager accessTokenManager, MailboxManager mailboxManager, HeadersAuthenticationExtractor authenticationExtractor) {
this.accessTokenManager = accessTokenManager;
this.mailboxManager = mailboxManager;
+ this.authenticationExtractor = authenticationExtractor;
}
@Override
- public MailboxSession createMailboxSession(Stream<String> authHeaders) throws MailboxSessionCreationException, NoValidAuthHeaderException {
+ public MailboxSession createMailboxSession(HttpServletRequest httpRequest) throws MailboxSessionCreationException, NoValidAuthHeaderException {
- Optional<String> username = authHeaders
+ Optional<String> username = authenticationExtractor.authHeaders(httpRequest)
.map(AccessToken::fromString)
.map(accessTokenManager::getUsernameFromToken)
.findFirst();
@@ -69,8 +72,8 @@ public class AccessTokenAuthenticationStrategy implements AuthenticationStrategy
}
@Override
- public boolean checkAuthorizationHeader(Stream<String> authHeaders) {
- return authHeaders
+ public boolean checkAuthorizationHeader(HttpServletRequest httpRequest) {
+ return authenticationExtractor.authHeaders(httpRequest)
.map(this::accessTokenFrom)
.anyMatch(this::isValid);
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
index a9ce14d..d62c1c2 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
@@ -19,10 +19,7 @@
package org.apache.james.jmap;
import java.io.IOException;
-import java.util.Collections;
-import java.util.Enumeration;
import java.util.List;
-import java.util.stream.Stream;
import javax.inject.Inject;
import javax.servlet.Filter;
@@ -50,7 +47,6 @@ public class AuthenticationFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationFilter.class);
public static final String MAILBOX_SESSION = "mailboxSession";
- private static final String AUTHORIZATION_HEADERS = "Authorization";
private final List<AuthenticationStrategy> authMethods;
@@ -71,9 +67,9 @@ public class AuthenticationFilter implements Filter {
try {
HttpServletRequest requestWithSession = authMethods.stream()
- .filter(auth -> auth.checkAuthorizationHeader(getAuthHeaders(httpRequest)))
+ .filter(auth -> auth.checkAuthorizationHeader(httpRequest))
.findFirst()
- .map(auth -> addSessionToRequest(httpRequest, createSession(auth, getAuthHeaders(httpRequest))))
+ .map(auth -> addSessionToRequest(httpRequest, createSession(auth, httpRequest)))
.orElseThrow(UnauthorizedException::new);
chain.doFilter(requestWithSession, response);
@@ -84,19 +80,13 @@ public class AuthenticationFilter implements Filter {
}
- private Stream<String> getAuthHeaders(HttpServletRequest httpRequest) {
- Enumeration<String> authHeaders = httpRequest.getHeaders(AUTHORIZATION_HEADERS);
-
- return authHeaders != null ? Collections.list(authHeaders).stream() : Stream.of();
- }
-
private HttpServletRequest addSessionToRequest(HttpServletRequest httpRequest, MailboxSession mailboxSession) {
httpRequest.setAttribute(MAILBOX_SESSION, mailboxSession);
return httpRequest;
}
- private MailboxSession createSession(AuthenticationStrategy authenticationMethod, Stream<String> authorizationHeaders) {
- return authenticationMethod.createMailboxSession(authorizationHeaders);
+ private MailboxSession createSession(AuthenticationStrategy authenticationMethod, HttpServletRequest httpRequest) {
+ return authenticationMethod.createMailboxSession(httpRequest);
}
@Override
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java
index 57ace0c..d75247a 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java
@@ -18,13 +18,13 @@
****************************************************************/
package org.apache.james.jmap;
-import java.util.stream.Stream;
+import javax.servlet.http.HttpServletRequest;
import org.apache.james.mailbox.MailboxSession;
public interface AuthenticationStrategy {
- MailboxSession createMailboxSession(Stream<String> requestHeaders);
+ MailboxSession createMailboxSession(HttpServletRequest httpRequest);
- boolean checkAuthorizationHeader(Stream<String> requestHeaders);
+ boolean checkAuthorizationHeader(HttpServletRequest httpRequest);
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java
index f6564b9..9d9c659 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java
@@ -21,10 +21,12 @@ package org.apache.james.jmap;
import java.util.stream.Stream;
import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
import org.apache.james.jmap.crypto.JwtTokenVerifier;
import org.apache.james.jmap.exceptions.MailboxSessionCreationException;
import org.apache.james.jmap.exceptions.NoValidAuthHeaderException;
+import org.apache.james.jmap.utils.HeadersAuthenticationExtractor;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.exception.MailboxException;
@@ -39,18 +41,20 @@ public class JWTAuthenticationStrategy implements AuthenticationStrategy {
@VisibleForTesting static final String AUTHORIZATION_HEADER_PREFIX = "Bearer ";
private final JwtTokenVerifier tokenManager;
private final MailboxManager mailboxManager;
+ private final HeadersAuthenticationExtractor authenticationExtractor;
@Inject
@VisibleForTesting
- JWTAuthenticationStrategy(JwtTokenVerifier tokenManager, MailboxManager mailboxManager) {
+ JWTAuthenticationStrategy(JwtTokenVerifier tokenManager, MailboxManager mailboxManager, HeadersAuthenticationExtractor authenticationExtractor) {
this.tokenManager = tokenManager;
this.mailboxManager = mailboxManager;
+ this.authenticationExtractor = authenticationExtractor;
}
@Override
- public MailboxSession createMailboxSession(Stream<String> authHeaders) throws MailboxSessionCreationException, NoValidAuthHeaderException {
+ public MailboxSession createMailboxSession(HttpServletRequest httpRequest) throws MailboxSessionCreationException, NoValidAuthHeaderException {
- Stream<String> userLoginStream = extractTokensFromAuthHeaders(authHeaders)
+ Stream<String> userLoginStream = extractTokensFromAuthHeaders(authenticationExtractor.authHeaders(httpRequest))
.filter(tokenManager::verify)
.map(tokenManager::extractLogin);
@@ -69,8 +73,8 @@ public class JWTAuthenticationStrategy implements AuthenticationStrategy {
}
@Override
- public boolean checkAuthorizationHeader(Stream<String> authHeaders) {
- return extractTokensFromAuthHeaders(authHeaders)
+ public boolean checkAuthorizationHeader(HttpServletRequest httpRequest) {
+ return extractTokensFromAuthHeaders(authenticationExtractor.authHeaders(httpRequest))
.anyMatch(tokenManager::verify);
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/HeadersAuthenticationExtractor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/HeadersAuthenticationExtractor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/HeadersAuthenticationExtractor.java
new file mode 100644
index 0000000..3bfb091
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/HeadersAuthenticationExtractor.java
@@ -0,0 +1,41 @@
+/****************************************************************
+ * 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.utils;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.stream.Stream;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.google.common.base.Preconditions;
+
+public class HeadersAuthenticationExtractor {
+
+ private static final String AUTHORIZATION_HEADERS = "Authorization";
+
+ public Stream<String> authHeaders(HttpServletRequest httpRequest) {
+ Preconditions.checkArgument(httpRequest != null, "'httpRequest' is mandatory");
+ Enumeration<String> authHeaders = httpRequest.getHeaders(AUTHORIZATION_HEADERS);
+
+ return authHeaders != null ? Collections.list(authHeaders).stream() : Stream.of();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java
index 83cae4b..91e18e2 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java
@@ -28,11 +28,14 @@ import static org.mockito.Mockito.when;
import java.util.UUID;
import java.util.stream.Stream;
+import javax.servlet.http.HttpServletRequest;
+
import org.apache.james.jmap.api.access.AccessToken;
import org.apache.james.jmap.api.access.exceptions.NotAnAccessTokenException;
import org.apache.james.jmap.crypto.AccessTokenManagerImpl;
import org.apache.james.jmap.exceptions.MailboxSessionCreationException;
import org.apache.james.jmap.exceptions.NoValidAuthHeaderException;
+import org.apache.james.jmap.utils.HeadersAuthenticationExtractor;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.exception.MailboxException;
@@ -45,24 +48,34 @@ public class AccessTokenAuthenticationStrategyTest {
private AccessTokenManagerImpl mockedAccessTokenManager;
private MailboxManager mockedMailboxManager;
private AccessTokenAuthenticationStrategy testee;
+ private HttpServletRequest request;
+ private HeadersAuthenticationExtractor mockAuthenticationExtractor;
@Before
public void setup() {
mockedAccessTokenManager = mock(AccessTokenManagerImpl.class);
mockedMailboxManager = mock(MailboxManager.class);
+ mockAuthenticationExtractor = mock(HeadersAuthenticationExtractor.class);
+ request = mock(HttpServletRequest.class);
- testee = new AccessTokenAuthenticationStrategy(mockedAccessTokenManager, mockedMailboxManager);
+ testee = new AccessTokenAuthenticationStrategy(mockedAccessTokenManager, mockedMailboxManager, mockAuthenticationExtractor);
}
@Test
public void createMailboxSessionShouldThrowWhenNoAuthProvided() {
- assertThatThrownBy(() -> testee.createMailboxSession(Stream.empty()))
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.empty());
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
.isExactlyInstanceOf(NoValidAuthHeaderException.class);
}
@Test
public void createMailboxSessionShouldThrowWhenAuthHeaderIsNotAnUUID() {
- assertThatThrownBy(() -> testee.createMailboxSession(Stream.of("bad")))
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of("bad"));
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
.isExactlyInstanceOf(NotAnAccessTokenException.class);
}
@@ -75,8 +88,11 @@ public class AccessTokenAuthenticationStrategyTest {
UUID authHeader = UUID.randomUUID();
when(mockedAccessTokenManager.getUsernameFromToken(AccessToken.fromString(authHeader.toString())))
.thenReturn(username);
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of(authHeader.toString()));
- assertThatThrownBy(() -> testee.createMailboxSession(Stream.of(authHeader.toString())))
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
.isExactlyInstanceOf(MailboxSessionCreationException.class);
}
@@ -91,24 +107,36 @@ public class AccessTokenAuthenticationStrategyTest {
UUID authHeader = UUID.randomUUID();
when(mockedAccessTokenManager.getUsernameFromToken(AccessToken.fromString(authHeader.toString())))
.thenReturn(username);
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of(authHeader.toString()));
+
- MailboxSession result = testee.createMailboxSession(Stream.of(authHeader.toString()));
+ MailboxSession result = testee.createMailboxSession(request);
assertThat(result).isEqualTo(fakeMailboxSession);
}
@Test
public void checkAuthorizationHeaderShouldReturnFalseWhenAuthHeaderIsEmpty() {
- assertThat(testee.checkAuthorizationHeader(Stream.empty())).isFalse();
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.empty());
+
+ assertThat(testee.checkAuthorizationHeader(request)).isFalse();
}
@Test
public void checkAuthorizationHeaderShouldReturnFalseWhenAuthHeaderIsInvalid() {
- assertThat(testee.checkAuthorizationHeader(Stream.of("bad"))).isFalse();
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of("bad"));
+
+ assertThat(testee.checkAuthorizationHeader(request)).isFalse();
}
@Test
public void checkAuthorizationHeaderShouldReturnFalseWhenAuthHeadersAreInvalid() {
- assertThat(testee.checkAuthorizationHeader(Stream.of("bad", "alsobad"))).isFalse();
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of("bad", "alsobad"));
+
+ assertThat(testee.checkAuthorizationHeader(request)).isFalse();
}
@Test
@@ -117,8 +145,11 @@ public class AccessTokenAuthenticationStrategyTest {
String validToken = UUID.randomUUID().toString();
when(mockedAccessTokenManager.isValid(AccessToken.fromString(validToken)))
.thenReturn(true);
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of(validToken));
- assertThat(testee.checkAuthorizationHeader(Stream.of(validToken))).isTrue();
+
+ assertThat(testee.checkAuthorizationHeader(request)).isTrue();
}
@Test
@@ -127,7 +158,10 @@ public class AccessTokenAuthenticationStrategyTest {
String validToken = UUID.randomUUID().toString();
when(mockedAccessTokenManager.isValid(AccessToken.fromString(validToken)))
.thenReturn(true);
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of("bad", validToken));
+
- assertThat(testee.checkAuthorizationHeader(Stream.of("bad", validToken))).isTrue();
+ assertThat(testee.checkAuthorizationHeader(request)).isTrue();
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
index 6da6ea1..837ff9f 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
@@ -26,7 +26,6 @@ import static org.mockito.Mockito.when;
import java.util.List;
import java.util.concurrent.TimeUnit;
-import java.util.stream.Stream;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
@@ -129,12 +128,12 @@ public class AuthenticationFilterTest {
}
@Override
- public MailboxSession createMailboxSession(Stream<String> requestHeaders) {
+ public MailboxSession createMailboxSession(HttpServletRequest httpRequest) {
return null;
}
@Override
- public boolean checkAuthorizationHeader(Stream<String> requestHeaders) {
+ public boolean checkAuthorizationHeader(HttpServletRequest httpRequest) {
return isAuthorized;
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java
index f4c8459..c96b7a8 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java
@@ -27,9 +27,12 @@ import static org.mockito.Mockito.when;
import java.util.stream.Stream;
+import javax.servlet.http.HttpServletRequest;
+
import org.apache.james.jmap.crypto.JwtTokenVerifier;
import org.apache.james.jmap.exceptions.MailboxSessionCreationException;
import org.apache.james.jmap.exceptions.NoValidAuthHeaderException;
+import org.apache.james.jmap.utils.HeadersAuthenticationExtractor;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.exception.MailboxException;
@@ -43,26 +46,35 @@ public class JWTAuthenticationStrategyTest {
private JWTAuthenticationStrategy testee;
private MailboxManager mockedMailboxManager;
private JwtTokenVerifier stubTokenVerifier;
+ private HttpServletRequest request;
+ private HeadersAuthenticationExtractor mockAuthenticationExtractor;
@Before
public void setup() {
- mockedMailboxManager = mock(MailboxManager.class);
-
stubTokenVerifier = mock(JwtTokenVerifier.class);
+ mockedMailboxManager = mock(MailboxManager.class);
+ mockAuthenticationExtractor = mock(HeadersAuthenticationExtractor.class);
+ request = mock(HttpServletRequest.class);
- testee = new JWTAuthenticationStrategy(stubTokenVerifier, mockedMailboxManager);
+ testee = new JWTAuthenticationStrategy(stubTokenVerifier, mockedMailboxManager, mockAuthenticationExtractor);
}
@Test
public void createMailboxSessionShouldThrowWhenAuthHeaderIsEmpty() throws Exception {
- assertThatThrownBy(() -> testee.createMailboxSession(Stream.empty()))
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.empty());
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
.isExactlyInstanceOf(NoValidAuthHeaderException.class);
}
@Test
public void createMailboxSessionShouldReturnEmptyWhenAuthHeaderIsInvalid() throws Exception {
- assertThatThrownBy(() -> testee.createMailboxSession(Stream.of("bad")))
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of("bad"));
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
.isExactlyInstanceOf(NoValidAuthHeaderException.class);
}
@@ -76,8 +88,10 @@ public class JWTAuthenticationStrategyTest {
when(stubTokenVerifier.extractLogin(validAuthHeader)).thenReturn(username);
when(mockedMailboxManager.createSystemSession(eq(username), any(Logger.class)))
.thenThrow(new MailboxException());
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of(fakeAuthHeaderWithPrefix));
- assertThatThrownBy(() -> testee.createMailboxSession(Stream.of(fakeAuthHeaderWithPrefix)))
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
.isExactlyInstanceOf(MailboxSessionCreationException.class);
}
@@ -92,14 +106,20 @@ public class JWTAuthenticationStrategyTest {
when(stubTokenVerifier.extractLogin(validAuthHeader)).thenReturn(username);
when(mockedMailboxManager.createSystemSession(eq(username), any(Logger.class)))
.thenReturn(fakeMailboxSession);
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of(fakeAuthHeaderWithPrefix));
+
- MailboxSession result = testee.createMailboxSession(Stream.of(fakeAuthHeaderWithPrefix));
+ MailboxSession result = testee.createMailboxSession(request);
assertThat(result).isEqualTo(fakeMailboxSession);
}
@Test
public void checkAuthorizationHeaderShouldReturnFalsewWhenAuthHeaderIsEmpty() {
- assertThat(testee.checkAuthorizationHeader(Stream.empty())).isFalse();
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.empty());
+
+ assertThat(testee.checkAuthorizationHeader(request)).isFalse();
}
@Test
@@ -108,8 +128,10 @@ public class JWTAuthenticationStrategyTest {
String fakeAuthHeaderWithPrefix = JWTAuthenticationStrategy.AUTHORIZATION_HEADER_PREFIX + wrongAuthHeader;
when(stubTokenVerifier.verify(wrongAuthHeader)).thenReturn(false);
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of(fakeAuthHeaderWithPrefix));
- assertThat(testee.checkAuthorizationHeader(Stream.of(fakeAuthHeaderWithPrefix))).isFalse();
+ assertThat(testee.checkAuthorizationHeader(request)).isFalse();
}
@Test
@@ -122,7 +144,10 @@ public class JWTAuthenticationStrategyTest {
Stream<String> authHeadersStream = Stream.of(wrongAuthHeader, invalidAuthHeader)
.map(h -> JWTAuthenticationStrategy.AUTHORIZATION_HEADER_PREFIX + h);
- assertThat(testee.checkAuthorizationHeader(authHeadersStream)).isFalse();
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(authHeadersStream);
+
+ assertThat(testee.checkAuthorizationHeader(request)).isFalse();
}
@Test
@@ -131,8 +156,10 @@ public class JWTAuthenticationStrategyTest {
String validAuthHeaderWithPrefix = JWTAuthenticationStrategy.AUTHORIZATION_HEADER_PREFIX + validAuthHeader;
when(stubTokenVerifier.verify(validAuthHeader)).thenReturn(true);
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of(validAuthHeaderWithPrefix));
- assertThat(testee.checkAuthorizationHeader(Stream.of(validAuthHeaderWithPrefix))).isTrue();
+ assertThat(testee.checkAuthorizationHeader(request)).isTrue();
}
@Test
@@ -145,7 +172,10 @@ public class JWTAuthenticationStrategyTest {
Stream<String> authHeadersStream = Stream.of(dummyAuthHeader, validAuthHeader)
.map(h -> JWTAuthenticationStrategy.AUTHORIZATION_HEADER_PREFIX + h);
- assertThat(testee.checkAuthorizationHeader(authHeadersStream)).isTrue();
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(authHeadersStream);
+
+ assertThat(testee.checkAuthorizationHeader(request)).isTrue();
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/3c7cc854/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/HeadersAuthenticationExtractorTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/HeadersAuthenticationExtractorTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/HeadersAuthenticationExtractorTest.java
new file mode 100644
index 0000000..e995cff
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/HeadersAuthenticationExtractorTest.java
@@ -0,0 +1,69 @@
+/****************************************************************
+ * 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.utils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class HeadersAuthenticationExtractorTest {
+
+ private HeadersAuthenticationExtractor testee;
+
+ @Before
+ public void setup() {
+ testee = new HeadersAuthenticationExtractor();
+ }
+
+ @Test
+ public void authHeadersShouldThrowWhenRequestIsNull() {
+ assertThatThrownBy(() -> testee.authHeaders(null))
+ .isExactlyInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ public void authHeadersShouldReturnEmptyStreamWhenNoAuthorizationHeader() {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getHeaders("Authorization"))
+ .thenReturn(Collections.emptyEnumeration());
+
+ assertThat(testee.authHeaders(request)).isEmpty();
+ }
+
+ @Test
+ public void authHeadersShouldReturnStreamOfHeadersWhenSome() {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ ImmutableList<String> expectedHeaders = ImmutableList.of("header", "otherHeader");
+ when(request.getHeaders("Authorization"))
+ .thenReturn(Collections.enumeration(expectedHeaders));
+
+ assertThat(testee.authHeaders(request)).containsOnlyElementsOf(expectedHeaders);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[4/4] james-project git commit: JAMES-1784 Add integration tests when
downloading attachment with access token
Posted by ad...@apache.org.
JAMES-1784 Add integration tests when downloading attachment with access token
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/85aeb1e4
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/85aeb1e4
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/85aeb1e4
Branch: refs/heads/master
Commit: 85aeb1e45b5d5cbffbe40b7c71f7ed264e57b5a6
Parents: b6f6ac9
Author: Antoine Duprat <ad...@linagora.com>
Authored: Fri Jul 1 14:56:30 2016 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Jul 8 09:54:07 2016 +0200
----------------------------------------------------------------------
.../integration/cucumber/DownloadStepdefs.java | 170 ++++++++++++++++---
.../resources/cucumber/DownloadEndpoint.feature | 51 ++++--
.../test/resources/cucumber/DownloadGet.feature | 5 +-
.../java/org/apache/james/jmap/JMAPServer.java | 2 +-
.../james/jmap/crypto/SignedTokenFactory.java | 4 +-
.../james/jmap/model/AttachmentAccessToken.java | 20 ++-
.../jmap/crypto/SignedTokenFactoryTest.java | 3 +-
.../jmap/crypto/SignedTokenManagerTest.java | 10 ++
8 files changed, 220 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/85aeb1e4/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
index b414de9..53fe11d 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
@@ -20,7 +20,7 @@
package org.apache.james.jmap.methods.integration.cucumber;
import static com.jayway.restassured.RestAssured.with;
-import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.isIn;
import static org.hamcrest.Matchers.notNullValue;
import java.util.Date;
@@ -31,10 +31,14 @@ import javax.inject.Inject;
import javax.mail.Flags;
import org.apache.james.jmap.api.access.AccessToken;
+import org.apache.james.jmap.model.AttachmentAccessToken;
import org.apache.james.mailbox.model.MailboxConstants;
import org.apache.james.mailbox.model.MailboxPath;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.response.Response;
@@ -49,12 +53,21 @@ import cucumber.runtime.java.guice.ScenarioScoped;
@ScenarioScoped
public class DownloadStepdefs {
+ private static final String ONE_ATTACHMENT_EML_ATTACHEMENT_BLOB_ID = "4000c5145f633410b80be368c44e1c394bff9437";
+ private static final String EXPIRED_ATTACHMENT_TOKEN = "usera@domain.tld_"
+ + "2016-06-29T13:41:22.124Z_"
+ + "DiZa0O14MjLWrAA8P6MG35Gt5CBp7mt5U1EH/M++rIoZK7nlGJ4dPW0dvZD7h4m3o5b/Yd8DXU5x2x4+s0HOOKzD7X0RMlsU7JHJMNLvTvRGWF/C+MUyC8Zce7DtnRVPEQX2uAZhL2PBABV07Vpa8kH+NxoS9CL955Bc1Obr4G+KN2JorADlocFQA6ElXryF5YS/HPZSvq1MTC6aJIP0ku8WRpRnbwgwJnn26YpcHXcJjbkCBtd9/BhlMV6xNd2hTBkfZmYdoNo+UKBaXWzLxAlbLuxjpxwvDNJfOEyWFPgHDoRvzP+G7KzhVWjanHAHrhF0GilEa/MKpOI1qHBSwA==";
+ private static final String INVALID_ATTACHMENT_TOKEN = "usera@domain.tld_"
+ + "2015-06-29T13:41:22.124Z_"
+ + "DiZa0O14MjLWrAA8P6MG35Gt5CBp7mt5U1EH/M++rIoZK7nlGJ4dPW0dvZD7h4m3o5b/Yd8DXU5x2x4+s0HOOKzD7X0RMlsU7JHJMNLvTvRGWF/C+MUyC8Zce7DtnRVPEQX2uAZhL2PBABV07Vpa8kH+NxoS9CL955Bc1Obr4G+KN2JorADlocFQA6ElXryF5YS/HPZSvq1MTC6aJIP0ku8WRpRnbwgwJnn26YpcHXcJjbkCBtd9/BhlMV6xNd2hTBkfZmYdoNo+UKBaXWzLxAlbLuxjpxwvDNJfOEyWFPgHDoRvzP+G7KzhVWjanHAHrhF0GilEa/MKpOI1qHBSwA==";
+
private final UserStepdefs userStepdefs;
private final MainStepdefs mainStepdefs;
private Response response;
private Multimap<String, String> attachmentsByMessageId;
private Map<String, String> blobIdByAttachmentId;
private ValidatableResponse validatableResponse;
+ private Map<AttachmentAccessTokenKey, AttachmentAccessToken> attachmentAccessTokens;
@Inject
private DownloadStepdefs(MainStepdefs mainStepdefs, UserStepdefs userStepdefs) {
@@ -62,6 +75,7 @@ public class DownloadStepdefs {
this.userStepdefs = userStepdefs;
this.attachmentsByMessageId = ArrayListMultimap.create();
this.blobIdByAttachmentId = new HashMap<>();
+ this.attachmentAccessTokens = new HashMap<>();
}
@Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a message \"([^\"]*)\" with an attachment \"([^\"]*)\"$")
@@ -95,38 +109,144 @@ public class DownloadStepdefs {
with.header("Authorization", accessToken.serialize());
}
- response = with.options("/download/myBlob");
+ response = with
+ .options("/download/" + ONE_ATTACHMENT_EML_ATTACHEMENT_BLOB_ID);
}
@When("^\"([^\"]*)\" downloads \"([^\"]*)\"$")
public void downloads(String username, String attachmentId) throws Throwable {
String blobId = blobIdByAttachmentId.get(attachmentId);
+ response = authenticatedDownloadRequest(blobId, username)
+ .get("/download/" + blobId);
+ }
+
+ private RequestSpecification authenticatedDownloadRequest(String blobId, String username) {
AccessToken accessToken = userStepdefs.tokenByUser.get(username);
- RequestSpecification with = with();
+ AttachmentAccessTokenKey key = new AttachmentAccessTokenKey(username, blobId);
+ if (attachmentAccessTokens.containsKey(key)) {
+ return with().param("access_token", attachmentAccessTokens.get(key).serialize());
+ }
if (accessToken != null) {
- with.header("Authorization", accessToken.serialize());
+ return with().header("Authorization", accessToken.serialize());
}
- response = with.get("/download/" + blobId);
+ return with();
}
-
- @When("^\"([^\"]*)\" asks for an attachment without blobId parameter$")
- public void getDownloadWithoutBlobId(String username) throws Throwable {
- AccessToken accessToken = userStepdefs.tokenByUser.get(username);
+ @When("^\"([^\"]*)\" is trusted for attachment \"([^\"]*)\"$")
+ public void attachmentAccessTokenFor(String username, String attachmentId) throws Throwable {
+ userStepdefs.connectUser(username);
+ trustForBlobId(blobIdByAttachmentId.get(attachmentId), username);
+ }
+
+ private static class AttachmentAccessTokenKey {
+
+ private String username;
+ private String blobId;
+
+ public AttachmentAccessTokenKey(String username, String blobId) {
+ this.username = username;
+ this.blobId = blobId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof AttachmentAccessTokenKey) {
+ AttachmentAccessTokenKey other = (AttachmentAccessTokenKey) obj;
+ return Objects.equal(username, other.username)
+ && Objects.equal(blobId, other.blobId);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(username, blobId);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects
+ .toStringHelper(this)
+ .add("username", username)
+ .add("blobId", blobId)
+ .toString();
+ }
+ }
+
+ private void trustForBlobId(String blobId, String username) {
+ String serializedAttachmentAccessToken =
+ with()
+ .header("Authorization", userStepdefs.tokenByUser.get(username).serialize())
+ .post("/download/" + blobId)
+ .then()
+ .extract()
+ .asString();
+ attachmentAccessTokens.put(
+ new AttachmentAccessTokenKey(username, blobId),
+ AttachmentAccessToken.from(
+ serializedAttachmentAccessToken,
+ blobId));
+ }
+
+ @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with a valid authentication token$")
+ public void downloadsWithValidToken(String username, String attachmentId) throws Throwable {
+ String blobId = blobIdByAttachmentId.get(attachmentId);
+
+ response = requestWithQueryParameterAuthentication(username, blobId)
+ .get("/download/" + attachmentId);
+ }
+
+ @When("^\"([^\"]*)\" downloads \"([^\"]*)\" without any authentication token$")
+ public void getDownloadWithoutToken(String username, String attachmentId) {
+ String blobId = blobIdByAttachmentId.get(attachmentId);
+ response = with().get("/download/" + blobId);
+ }
+
+ @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with an empty authentication token$")
+ public void getDownloadWithEmptyToken(String username, String attachmentId) {
+ String blobId = blobIdByAttachmentId.get(attachmentId);
response = with()
- .header("Authorization", accessToken.serialize())
- .get("/download/");
+ .param("access_token", "")
+ .get("/download/" + blobId);
}
-
- @When("^\"([^\"]*)\" asks for an attachment with wrong blobId$")
- public void getDownloadWithWrongBlobId(String username) throws Throwable {
- AccessToken accessToken = userStepdefs.tokenByUser.get(username);
+ @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with a bad authentication token$")
+ public void getDownloadWithBadToken(String username, String attachmentId) {
+ String blobId = blobIdByAttachmentId.get(attachmentId);
response = with()
- .header("Authorization", accessToken.serialize())
+ .param("access_token", "bad")
+ .get("/download/" + blobId);
+ }
+
+ @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with an invalid authentication token$")
+ public void getDownloadWithUnknownToken(String username, String attachmentId) {
+ String blobId = blobIdByAttachmentId.get(attachmentId);
+ response = with()
+ .param("access_token", INVALID_ATTACHMENT_TOKEN)
+ .get("/download/" + blobId);
+ }
+
+ @When("^\"([^\"]*)\" downloads \"([^\"]*)\" without blobId parameter$")
+ public void getDownloadWithoutBlobId(String username, String attachmentId) throws Throwable {
+ String blobId = blobIdByAttachmentId.get(attachmentId);
+
+ response = requestWithQueryParameterAuthentication(username, blobId)
+ .get("/download/");
+ }
+
+ @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with wrong blobId$")
+ public void getDownloadWithWrongBlobId(String username, String attachmentId) throws Throwable {
+ String blobId = blobIdByAttachmentId.get(attachmentId);
+
+ response = requestWithQueryParameterAuthentication(username, blobId)
.get("/download/badbadbadbadbadbadbadbadbadbadbadbadbadb");
}
+ private RequestSpecification requestWithQueryParameterAuthentication(String username, String blobId) {
+ trustForBlobId(blobId, username);
+ return authenticatedDownloadRequest(blobId, username);
+ }
+
@When("^\"([^\"]*)\" asks for a token for attachment \"([^\"]*)\"$")
public void postDownload(String username, String attachmentId) throws Throwable {
String blobId = blobIdByAttachmentId.get(attachmentId);
@@ -142,18 +262,22 @@ public class DownloadStepdefs {
@When("^\"([^\"]*)\" downloads \"([^\"]*)\" with \"([^\"]*)\" name$")
public void downloadsWithName(String username, String attachmentId, String name) {
String blobId = blobIdByAttachmentId.get(attachmentId);
- AccessToken accessToken = userStepdefs.tokenByUser.get(username);
- RequestSpecification with = with();
- if (accessToken != null) {
- with.header("Authorization", accessToken.serialize());
- }
- response = with.get("/download/" + blobId + "/" + name);
+ response = authenticatedDownloadRequest(blobId, username)
+ .get("/download/" + blobId + "/" + name);
+ }
+
+ @When("^\"([^\"]*)\" downloads \"([^\"]*)\" with an expired token$")
+ public void getDownloadWithExpiredToken(String username, String attachmentId) {
+ String blobId = blobIdByAttachmentId.get(attachmentId);
+ response = with()
+ .param("access_token", EXPIRED_ATTACHMENT_TOKEN)
+ .get("/download/" + blobId);
}
@Then("^the user should be authorized$")
public void httpStatusDifferentFromUnauthorized() {
response.then()
- .statusCode(not(401));
+ .statusCode(isIn(ImmutableList.of(200, 404)));
}
@Then("^the user should not be authorized$")
http://git-wip-us.apache.org/repos/asf/james-project/blob/85aeb1e4/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
index d059572..e46a4fe 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
@@ -17,35 +17,58 @@ Feature: Download endpoint
When "usera@domain.tld" checks for the availability of the attachment endpoint
Then the user should be authorized
- Scenario: An authenticated user should have access to the download endpoint
- Given "usera@domain.tld" is connected
- When "usera@domain.tld" downloads "a1"
- Then the user should be authorized
-
- @Ignore
Scenario: An unauthenticated user should not have access to the download endpoint
When "usera@domain.tld" downloads "a1"
Then the user should not be authorized
- Scenario: A authenticated user should not have access to the download endpoint without a blobId
- Given "usera@domain.tld" is connected
- When "usera@domain.tld" asks for an attachment without blobId parameter
- Then the user should receive a bad request response
+ Scenario: A user should not have access to the download endpoint without the authentication token
+ When "usera@domain.tld" downloads "a1" without any authentication token
+ Then the user should not be authorized
+
+ Scenario: A user should not have access to the download endpoint with an empty authentication token
+ When "usera@domain.tld" downloads "a1" with an empty authentication token
+ Then the user should not be authorized
+
+ Scenario: A user should not have access to the download endpoint with a bad authentication token
+ When "usera@domain.tld" downloads "a1" with a bad authentication token
+ Then the user should not be authorized
+
+ Scenario: A user should not have access to the download endpoint with an unknown authentication token
+ When "usera@domain.tld" downloads "a1" with an invalid authentication token
+ Then the user should not be authorized
+
+ Scenario: A user should not have access to the download endpoint when an authentication token has expired
+ When "usera@domain.tld" downloads "a1" with an expired token
+ Then the user should not be authorized
+ Scenario: A user should not have access to the download endpoint without a blobId
+ Given "usera@domain.tld" is trusted for attachment "a1"
+ When "usera@domain.tld" downloads "a1" without blobId parameter
+ Then the user should not be authorized
Scenario: A user should not retrieve anything when using wrong blobId
+ Given "usera@domain.tld" is trusted for attachment "a1"
+ When "usera@domain.tld" downloads "a1" with wrong blobId
+ Then the user should not be authorized
+
+ 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"
+ Then the user should be authorized
+
+ Scenario: An authenticated user should have access to the download endpoint
Given "usera@domain.tld" is connected
- When "usera@domain.tld" asks for an attachment with wrong blobId
- Then the user should receive a not found response
+ When "usera@domain.tld" downloads "a1"
+ Then the user should be authorized
@Ignore
- Scenario: A user should not have access to someone else attachment
+ Scenario: An authenticated user should not have access to someone else attachment
Given "userb@domain.tld" is connected
When "userb@domain.tld" downloads "a1"
Then the user should receive a not found response
@Ignore
- Scenario: A user should have access to a shared attachment
+ Scenario: An authenticated user should have access to a shared attachment
Given "usera@domain.tld" shares its mailbox "INBOX" with "userb@domain.tld"
And "userb@domain.tld" is connected
When "userb@domain.tld" downloads "a1"
http://git-wip-us.apache.org/repos/asf/james-project/blob/85aeb1e4/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
index bf3d21a..ccd7eef 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
@@ -13,8 +13,9 @@ Feature: Download GET
Then the user should receive that attachment
Scenario: Getting an attachment with an unknown blobId
- When "username@domain.tld" downloads "123"
- Then the user should receive a not found response
+ Given "username@domain.tld" mailbox "inbox" contains a message "1" with an attachment "2"
+ When "username@domain.tld" downloads "2" with a valid authentication token
+ Then the user should not be authorized
Scenario: Getting an attachment previously stored with a desired name
Given "username@domain.tld" mailbox "inbox" contains a message "1" with an attachment "2"
http://git-wip-us.apache.org/repos/asf/james-project/blob/85aeb1e4/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java
index 7d235a4..e1c3ba5 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServer.java
@@ -58,7 +58,7 @@ public class JMAPServer implements Configurable {
.serveAsOneLevelTemplate(JMAPUrls.DOWNLOAD)
.with(downloadServlet)
.filterAsOneLevelTemplate(JMAPUrls.DOWNLOAD)
- .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("GET").and("OPTIONS").only()))
+ .with(new AllowAllCrossOriginRequests(bypass(authenticationFilter).on("OPTIONS").only()))
.only()
.serve(JMAPUrls.UPLOAD)
.with(uploadServlet)
http://git-wip-us.apache.org/repos/asf/james-project/blob/85aeb1e4/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/SignedTokenFactory.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/SignedTokenFactory.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/SignedTokenFactory.java
index 7154a32..594bff3 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/SignedTokenFactory.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/SignedTokenFactory.java
@@ -65,8 +65,8 @@ public class SignedTokenFactory implements SimpleTokenFactory {
.blobId(blobId)
.expirationDate(expirationTime)
.signature(signatureHandler.sign(Joiner.on(AttachmentAccessToken.SEPARATOR)
- .join(username,
- blobId,
+ .join(blobId,
+ username,
DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(expirationTime))))
.build();
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/85aeb1e4/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AttachmentAccessToken.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AttachmentAccessToken.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AttachmentAccessToken.java
index 4d13c75..2188b1e 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AttachmentAccessToken.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AttachmentAccessToken.java
@@ -21,11 +21,15 @@ package org.apache.james.jmap.model;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
+import java.util.List;
import java.util.Objects;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.Iterables;
public class AttachmentAccessToken implements SignedExpiringToken {
@@ -34,7 +38,21 @@ public class AttachmentAccessToken implements SignedExpiringToken {
public static Builder builder() {
return new Builder();
}
-
+
+ public static AttachmentAccessToken from(String serializedAttachmentAccessToken, String blobId) {
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(serializedAttachmentAccessToken), "'AttachmentAccessToken' is mandatory");
+ List<String> split = Splitter.on(SEPARATOR).splitToList(serializedAttachmentAccessToken);
+ Preconditions.checkArgument(split.size() == 3, "Wrong 'AttachmentAccessToken'");
+
+ String defaultValue = null;
+ return builder()
+ .blobId(blobId)
+ .username(Iterables.get(split, 0, defaultValue))
+ .expirationDate(ZonedDateTime.parse(Iterables.get(split, 1, defaultValue)))
+ .signature(Iterables.get(split, 2, defaultValue))
+ .build();
+ }
+
public static class Builder {
private String username;
private String blobId;
http://git-wip-us.apache.org/repos/asf/james-project/blob/85aeb1e4/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenFactoryTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenFactoryTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenFactoryTest.java
index 371083f..dfe8c18 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenFactoryTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenFactoryTest.java
@@ -73,7 +73,6 @@ public class SignedTokenFactoryTest {
public void generateAttachmentAccessTokenShouldHaveTheRightOutPut() throws Exception {
zonedDateTimeProvider.setFixedDateTime(DATE);
assertThat(toKenFactory.generateAttachmentAccessToken("user", "blobId").serialize())
- .isEqualTo("user_2011-12-03T10:20:30+01:00_UAmjTzvmmIwvE1Yw54tE7jC1Q2nCJ1l3XX1703kYmLIeOZe7fNSLM6V8CzPFEvZ+Y4H+UD4UTkNHbmgcPbxesITnby+UfT/tIiTppJhXJvtTxSoTy9vuAJrW9/kJh6CruqtSM+BUEkLKuuzJySmvDkaHSaXwot4egGXaJ9yHgjEh2PT3uA0O0JjRNB2x8oa370fFSZsT2QgXrqeqHWWO1j6IrAf4UcyhvjNkJBK9TVNubfqGKuCZ4dz2Rm/CUvp13CpzUoVqBS1nJ1VaIw94L2rX8RkAMTlV7AXKB3kPiBX7MdGp2NBiAUlYlOLjflYl8plnv/QrRCmfGxnsvv4WVQ==");
+ .isEqualTo("user_2011-12-03T10:20:30+01:00_eSg1mVxMpqw5/u6wsTAatP7hoHDoI7blEW0hxGPrRMMj3hECT+YhbUCdhz9Lb4U+jsYPgNLDuAHwxin79xXfLoq0nVsogEE32svRYVvbaDpro+EOtkAHhYnYxWnAGxB/70u7Zyw0oYGmWOwkCkLDFsWKglMp9IUpOJQP50zbzbdW+4dKlAi/8VmN8jFyZx40envRbgEn4Q2QQbnUH/7F9+vdLIl+bAfcj6QlevqFRsUkmTZelkv1rtGUAvnPSBQL4TeBx5Qk/eEiw8IbB2lbCIAoIFZC6Vl8QOO5Y6LFzmqHL9i0BjvuoiZ8FKQS0pGd5CU6pwc7sv0xD82Vx1eFiw==");
}
-
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/85aeb1e4/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenManagerTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenManagerTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenManagerTest.java
index c371f0b..b31f0df 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenManagerTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenManagerTest.java
@@ -27,6 +27,7 @@ import java.time.format.DateTimeFormatter;
import org.apache.james.jmap.FixedDateZonedDateTimeProvider;
import org.apache.james.jmap.api.SimpleTokenManager.TokenStatus;
+import org.apache.james.jmap.model.AttachmentAccessToken;
import org.apache.james.jmap.model.ContinuationToken;
import org.junit.Before;
import org.junit.Test;
@@ -168,4 +169,13 @@ public class SignedTokenManagerTest {
ContinuationToken pirateContinuationToken = new ContinuationToken("user", DATE.plusMinutes(15), "fake");
assertThat(tokenManager.getValidity(pirateContinuationToken)).isEqualTo(TokenStatus.INVALID);
}
+
+ @Test
+ public void signedAttachmentAccessTokenShouldBeValidated() {
+ String blobId = "blobId";
+ zonedDateTimeProvider.setFixedDateTime(DATE);
+ String serializedToken = tokenFactory.generateAttachmentAccessToken("user", blobId).serialize();
+
+ assertThat(tokenManager.isValid(AttachmentAccessToken.from(serializedToken, blobId))).isTrue();
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[3/4] james-project git commit: JAMES-1784 Add
QueryParameterAccessTokenAuthenticationStrategy
Posted by ad...@apache.org.
JAMES-1784 Add QueryParameterAccessTokenAuthenticationStrategy
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b6f6ac9a
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b6f6ac9a
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b6f6ac9a
Branch: refs/heads/master
Commit: b6f6ac9af0961f425395896773c2d4f1e82d328f
Parents: 6262735
Author: Antoine Duprat <ad...@linagora.com>
Authored: Fri Jul 1 14:55:51 2016 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Jul 8 09:54:06 2016 +0200
----------------------------------------------------------------------
.../org/apache/james/jmap/JMAPCommonModule.java | 6 +-
...ameterAccessTokenAuthenticationStrategy.java | 85 ++++++++++++++++++
...erAccessTokenAuthenticationStrategyTest.java | 94 ++++++++++++++++++++
3 files changed, 183 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/b6f6ac9a/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java b/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java
index 0d5362f..5a9b6a4 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/JMAPCommonModule.java
@@ -76,10 +76,12 @@ public class JMAPCommonModule extends AbstractModule {
@Provides
public List<AuthenticationStrategy> authStrategies(
AccessTokenAuthenticationStrategy accessTokenAuthenticationStrategy,
- JWTAuthenticationStrategy jwtAuthenticationStrategy) {
+ JWTAuthenticationStrategy jwtAuthenticationStrategy,
+ QueryParameterAccessTokenAuthenticationStrategy queryParameterAuthenticationStrategy) {
return ImmutableList.of(
jwtAuthenticationStrategy,
- accessTokenAuthenticationStrategy);
+ accessTokenAuthenticationStrategy,
+ queryParameterAuthenticationStrategy);
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/b6f6ac9a/server/protocols/jmap/src/main/java/org/apache/james/jmap/QueryParameterAccessTokenAuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/QueryParameterAccessTokenAuthenticationStrategy.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/QueryParameterAccessTokenAuthenticationStrategy.java
new file mode 100644
index 0000000..498ba91
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/QueryParameterAccessTokenAuthenticationStrategy.java
@@ -0,0 +1,85 @@
+/****************************************************************
+ * 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;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.james.jmap.api.SimpleTokenManager;
+import org.apache.james.jmap.exceptions.MailboxSessionCreationException;
+import org.apache.james.jmap.exceptions.NoValidAuthHeaderException;
+import org.apache.james.jmap.exceptions.UnauthorizedException;
+import org.apache.james.jmap.model.AttachmentAccessToken;
+import org.apache.james.jmap.utils.DownloadPath;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+
+public class QueryParameterAccessTokenAuthenticationStrategy implements AuthenticationStrategy {
+
+ private static final Logger LOG = LoggerFactory.getLogger(QueryParameterAccessTokenAuthenticationStrategy.class);
+ private static final String AUTHENTICATION_PARAMETER = "access_token";
+
+ private final SimpleTokenManager tokenManager;
+ private final MailboxManager mailboxManager;
+
+ @Inject
+ @VisibleForTesting
+ QueryParameterAccessTokenAuthenticationStrategy(SimpleTokenManager tokenManager, MailboxManager mailboxManager) {
+ this.tokenManager = tokenManager;
+ this.mailboxManager = mailboxManager;
+ }
+
+ @Override
+ public MailboxSession createMailboxSession(HttpServletRequest httpRequest) throws MailboxSessionCreationException, NoValidAuthHeaderException {
+
+ return getAccessToken(httpRequest)
+ .filter(tokenManager::isValid)
+ .map(AttachmentAccessToken::getUsername)
+ .map(this::createSystemSession)
+ .orElseThrow(() -> new UnauthorizedException());
+ }
+
+ private MailboxSession createSystemSession(String username) {
+ try {
+ return mailboxManager.createSystemSession(username, LOG);
+ } catch (MailboxException e) {
+ throw new MailboxSessionCreationException(e);
+ }
+ }
+
+ private Optional<AttachmentAccessToken> getAccessToken(HttpServletRequest httpRequest) {
+ try {
+ return Optional.of(AttachmentAccessToken.from(httpRequest.getParameter(AUTHENTICATION_PARAMETER), getBlobId(httpRequest)));
+ } catch (IllegalArgumentException e) {
+ return Optional.empty();
+ }
+ }
+
+ private String getBlobId(HttpServletRequest httpRequest) {
+ String pathInfo = httpRequest.getPathInfo();
+ return DownloadPath.from(pathInfo).getBlobId();
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/b6f6ac9a/server/protocols/jmap/src/test/java/org/apache/james/jmap/QueryParameterAccessTokenAuthenticationStrategyTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/QueryParameterAccessTokenAuthenticationStrategyTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/QueryParameterAccessTokenAuthenticationStrategyTest.java
new file mode 100644
index 0000000..a04d75d
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/QueryParameterAccessTokenAuthenticationStrategyTest.java
@@ -0,0 +1,94 @@
+/****************************************************************
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.james.jmap.api.SimpleTokenManager;
+import org.apache.james.jmap.exceptions.MailboxSessionCreationException;
+import org.apache.james.jmap.exceptions.UnauthorizedException;
+import org.apache.james.jmap.model.AttachmentAccessToken;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+
+public class QueryParameterAccessTokenAuthenticationStrategyTest {
+
+ private static final String USERNAME = "usera@domain.tld";
+ private static final String VALID_ATTACHMENT_TOKEN = "usera@domain.tld_"
+ + "2016-06-29T13:41:22.124Z_"
+ + "DiZa0O14MjLWrAA8P6MG35Gt5CBp7mt5U1EH/M++rIoZK7nlGJ4dPW0dvZD7h4m3o5b/Yd8DXU5x2x4+s0HOOKzD7X0RMlsU7JHJMNLvTvRGWF/C+MUyC8Zce7DtnRVPEQX2uAZhL2PBABV07Vpa8kH+NxoS9CL955Bc1Obr4G+KN2JorADlocFQA6ElXryF5YS/HPZSvq1MTC6aJIP0ku8WRpRnbwgwJnn26YpcHXcJjbkCBtd9/BhlMV6xNd2hTBkfZmYdoNo+UKBaXWzLxAlbLuxjpxwvDNJfOEyWFPgHDoRvzP+G7KzhVWjanHAHrhF0GilEa/MKpOI1qHBSwA==";
+
+ private SimpleTokenManager mockedSimpleTokenManager;
+ private MailboxManager mockedMailboxManager;
+ private QueryParameterAccessTokenAuthenticationStrategy testee;
+ private HttpServletRequest request;
+
+ @Before
+ public void setup() {
+ mockedSimpleTokenManager = mock(SimpleTokenManager.class);
+ mockedMailboxManager = mock(MailboxManager.class);
+ request = mock(HttpServletRequest.class);
+
+ testee = new QueryParameterAccessTokenAuthenticationStrategy(mockedSimpleTokenManager, mockedMailboxManager);
+ }
+
+ @Test
+ public void createMailboxSessionShouldThrowWhenNoAccessTokenProvided() {
+ when(request.getParameter("access_token"))
+ .thenReturn(null);
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
+ .isExactlyInstanceOf(UnauthorizedException.class);
+ }
+
+ @Test
+ public void createMailboxSessionShouldThrowWhenAccessTokenIsNotValid() {
+ when(request.getParameter("access_token"))
+ .thenReturn("bad");
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
+ .isExactlyInstanceOf(UnauthorizedException.class);
+ }
+
+ @Test
+ public void createMailboxSessionShouldThrowWhenMailboxExceptionHasOccurred() throws Exception {
+ when(mockedMailboxManager.createSystemSession(eq(USERNAME), any(Logger.class)))
+ .thenThrow(new MailboxException());
+
+ when(request.getParameter("access_token"))
+ .thenReturn(VALID_ATTACHMENT_TOKEN);
+ when(request.getPathInfo())
+ .thenReturn("/blobId");
+
+ when(mockedSimpleTokenManager.isValid(AttachmentAccessToken.from(VALID_ATTACHMENT_TOKEN, "blobId")))
+ .thenReturn(true);
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
+ .isExactlyInstanceOf(MailboxSessionCreationException.class);
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[2/4] james-project git commit: JAMES-1784 Remove
checkAuthorizationHeader in AuthenticationStrategy
Posted by ad...@apache.org.
JAMES-1784 Remove checkAuthorizationHeader in AuthenticationStrategy
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/62627357
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/62627357
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/62627357
Branch: refs/heads/master
Commit: 62627357717844ed0630b68fb5541836639763af
Parents: 3c7cc85
Author: Antoine Duprat <ad...@linagora.com>
Authored: Mon Jul 4 13:48:31 2016 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Jul 8 09:54:06 2016 +0200
----------------------------------------------------------------------
.../jmap/AccessTokenAuthenticationStrategy.java | 22 +----
.../apache/james/jmap/AuthenticationFilter.java | 13 ++-
.../james/jmap/AuthenticationStrategy.java | 2 -
.../james/jmap/JWTAuthenticationStrategy.java | 6 --
.../AccessTokenAuthenticationStrategyTest.java | 80 +++++++------------
.../james/jmap/AuthenticationFilterTest.java | 27 +++++--
.../jmap/JWTAuthenticationStrategyTest.java | 84 +++++---------------
7 files changed, 76 insertions(+), 158 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/62627357/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java
index d190ebd..57d903a 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AccessTokenAuthenticationStrategy.java
@@ -25,7 +25,6 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.james.jmap.api.AccessTokenManager;
import org.apache.james.jmap.api.access.AccessToken;
-import org.apache.james.jmap.api.access.exceptions.NotAnAccessTokenException;
import org.apache.james.jmap.exceptions.MailboxSessionCreationException;
import org.apache.james.jmap.exceptions.NoValidAuthHeaderException;
import org.apache.james.jmap.utils.HeadersAuthenticationExtractor;
@@ -58,6 +57,7 @@ public class AccessTokenAuthenticationStrategy implements AuthenticationStrategy
Optional<String> username = authenticationExtractor.authHeaders(httpRequest)
.map(AccessToken::fromString)
+ .filter(accessTokenManager::isValid)
.map(accessTokenManager::getUsernameFromToken)
.findFirst();
@@ -70,24 +70,4 @@ public class AccessTokenAuthenticationStrategy implements AuthenticationStrategy
}
throw new NoValidAuthHeaderException();
}
-
- @Override
- public boolean checkAuthorizationHeader(HttpServletRequest httpRequest) {
- return authenticationExtractor.authHeaders(httpRequest)
- .map(this::accessTokenFrom)
- .anyMatch(this::isValid);
- }
-
- private Optional<AccessToken> accessTokenFrom(String header) {
- try {
- return Optional.of(AccessToken.fromString(header));
- } catch (NotAnAccessTokenException e) {
- return Optional.empty();
- }
- }
-
- private boolean isValid(Optional<AccessToken> token) {
- return token.map(accessTokenManager::isValid)
- .orElse(false);
- }
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/62627357/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
index d62c1c2..14823a5 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
@@ -20,6 +20,7 @@ package org.apache.james.jmap;
import java.io.IOException;
import java.util.List;
+import java.util.stream.Stream;
import javax.inject.Inject;
import javax.servlet.Filter;
@@ -67,9 +68,9 @@ public class AuthenticationFilter implements Filter {
try {
HttpServletRequest requestWithSession = authMethods.stream()
- .filter(auth -> auth.checkAuthorizationHeader(httpRequest))
+ .flatMap(auth -> createSession(auth, httpRequest))
.findFirst()
- .map(auth -> addSessionToRequest(httpRequest, createSession(auth, httpRequest)))
+ .map(mailboxSession -> addSessionToRequest(httpRequest, mailboxSession))
.orElseThrow(UnauthorizedException::new);
chain.doFilter(requestWithSession, response);
@@ -85,8 +86,12 @@ public class AuthenticationFilter implements Filter {
return httpRequest;
}
- private MailboxSession createSession(AuthenticationStrategy authenticationMethod, HttpServletRequest httpRequest) {
- return authenticationMethod.createMailboxSession(httpRequest);
+ private Stream<MailboxSession> createSession(AuthenticationStrategy authenticationMethod, HttpServletRequest httpRequest) {
+ try {
+ return Stream.of(authenticationMethod.createMailboxSession(httpRequest));
+ } catch (Exception e) {
+ return Stream.empty();
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/james-project/blob/62627357/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java
index d75247a..aab2286 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationStrategy.java
@@ -25,6 +25,4 @@ import org.apache.james.mailbox.MailboxSession;
public interface AuthenticationStrategy {
MailboxSession createMailboxSession(HttpServletRequest httpRequest);
-
- boolean checkAuthorizationHeader(HttpServletRequest httpRequest);
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/62627357/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java
index 9d9c659..a7e91be 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/JWTAuthenticationStrategy.java
@@ -72,12 +72,6 @@ public class JWTAuthenticationStrategy implements AuthenticationStrategy {
.orElseThrow(() -> new NoValidAuthHeaderException());
}
- @Override
- public boolean checkAuthorizationHeader(HttpServletRequest httpRequest) {
- return extractTokensFromAuthHeaders(authenticationExtractor.authHeaders(httpRequest))
- .anyMatch(tokenManager::verify);
- }
-
private Stream<String> extractTokensFromAuthHeaders(Stream<String> authHeaders) {
return authHeaders
.filter(h -> h.startsWith(AUTHORIZATION_HEADER_PREFIX))
http://git-wip-us.apache.org/repos/asf/james-project/blob/62627357/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java
index 91e18e2..b1c71b6 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/AccessTokenAuthenticationStrategyTest.java
@@ -80,17 +80,38 @@ public class AccessTokenAuthenticationStrategyTest {
}
@Test
+ public void createMailboxSessionShouldThrowWhenAuthHeaderIsInvalid() throws Exception {
+ String username = "123456789";
+ MailboxSession fakeMailboxSession = mock(MailboxSession.class);
+
+ when(mockedMailboxManager.createSystemSession(eq(username), any(Logger.class)))
+ .thenReturn(fakeMailboxSession);
+
+ UUID authHeader = UUID.randomUUID();
+ when(mockedAccessTokenManager.getUsernameFromToken(AccessToken.fromString(authHeader.toString())))
+ .thenReturn(username);
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of(authHeader.toString()));
+
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
+ .isExactlyInstanceOf(NoValidAuthHeaderException.class);
+ }
+
+ @Test
public void createMailboxSessionShouldThrowWhenMailboxExceptionHasOccurred() throws Exception {
String username = "username";
when(mockedMailboxManager.createSystemSession(eq(username), any(Logger.class)))
.thenThrow(new MailboxException());
UUID authHeader = UUID.randomUUID();
- when(mockedAccessTokenManager.getUsernameFromToken(AccessToken.fromString(authHeader.toString())))
+ AccessToken accessToken = AccessToken.fromString(authHeader.toString());
+ when(mockedAccessTokenManager.getUsernameFromToken(accessToken))
.thenReturn(username);
when(mockAuthenticationExtractor.authHeaders(request))
.thenReturn(Stream.of(authHeader.toString()));
-
+ when(mockedAccessTokenManager.isValid(accessToken))
+ .thenReturn(true);
assertThatThrownBy(() -> testee.createMailboxSession(request))
.isExactlyInstanceOf(MailboxSessionCreationException.class);
@@ -105,63 +126,16 @@ public class AccessTokenAuthenticationStrategyTest {
.thenReturn(fakeMailboxSession);
UUID authHeader = UUID.randomUUID();
- when(mockedAccessTokenManager.getUsernameFromToken(AccessToken.fromString(authHeader.toString())))
+ AccessToken accessToken = AccessToken.fromString(authHeader.toString());
+ when(mockedAccessTokenManager.getUsernameFromToken(accessToken))
.thenReturn(username);
when(mockAuthenticationExtractor.authHeaders(request))
.thenReturn(Stream.of(authHeader.toString()));
+ when(mockedAccessTokenManager.isValid(accessToken))
+ .thenReturn(true);
MailboxSession result = testee.createMailboxSession(request);
assertThat(result).isEqualTo(fakeMailboxSession);
}
-
- @Test
- public void checkAuthorizationHeaderShouldReturnFalseWhenAuthHeaderIsEmpty() {
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(Stream.empty());
-
- assertThat(testee.checkAuthorizationHeader(request)).isFalse();
- }
-
- @Test
- public void checkAuthorizationHeaderShouldReturnFalseWhenAuthHeaderIsInvalid() {
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(Stream.of("bad"));
-
- assertThat(testee.checkAuthorizationHeader(request)).isFalse();
- }
-
- @Test
- public void checkAuthorizationHeaderShouldReturnFalseWhenAuthHeadersAreInvalid() {
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(Stream.of("bad", "alsobad"));
-
- assertThat(testee.checkAuthorizationHeader(request)).isFalse();
- }
-
- @Test
- public void checkAuthorizationHeaderShouldReturnTrueWhenAuthHeaderIsValid() {
-
- String validToken = UUID.randomUUID().toString();
- when(mockedAccessTokenManager.isValid(AccessToken.fromString(validToken)))
- .thenReturn(true);
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(Stream.of(validToken));
-
-
- assertThat(testee.checkAuthorizationHeader(request)).isTrue();
- }
-
- @Test
- public void checkAuthorizationHeaderShouldReturnTrueWhenOneAuthHeaderIsValid() {
-
- String validToken = UUID.randomUUID().toString();
- when(mockedAccessTokenManager.isValid(AccessToken.fromString(validToken)))
- .thenReturn(true);
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(Stream.of("bad", validToken));
-
-
- assertThat(testee.checkAuthorizationHeader(request)).isTrue();
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/62627357/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
index 837ff9f..8a189b7 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
@@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.james.jmap.api.access.AccessToken;
import org.apache.james.jmap.api.access.AccessTokenRepository;
+import org.apache.james.jmap.exceptions.MailboxSessionCreationException;
import org.apache.james.jmap.memory.access.MemoryAccessTokenRepository;
import org.apache.james.mailbox.MailboxSession;
import org.junit.Before;
@@ -99,6 +100,20 @@ public class AuthenticationFilterTest {
}
@Test
+ public void filterShouldChainAuthorizationStrategy() throws Exception {
+ AccessToken token = AccessToken.fromString(TOKEN);
+ when(mockedRequest.getHeader("Authorization"))
+ .thenReturn(TOKEN);
+
+ accessTokenRepository.addToken("user@domain.tld", token);
+
+ AuthenticationFilter sut = new AuthenticationFilter(ImmutableList.of(new FakeAuthenticationStrategy(false), new FakeAuthenticationStrategy(true)));
+ sut.doFilter(mockedRequest, mockedResponse, filterChain);
+
+ verify(filterChain).doFilter(any(ServletRequest.class), eq(mockedResponse));
+ }
+
+ @Test
public void filterShouldReturnUnauthorizedOnBadAuthorizationHeader() throws Exception {
when(mockedRequest.getHeader("Authorization"))
.thenReturn("bad");
@@ -119,7 +134,7 @@ public class AuthenticationFilterTest {
verify(mockedResponse).sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
- private class FakeAuthenticationStrategy implements AuthenticationStrategy {
+ private static class FakeAuthenticationStrategy implements AuthenticationStrategy {
private final boolean isAuthorized;
@@ -129,12 +144,10 @@ public class AuthenticationFilterTest {
@Override
public MailboxSession createMailboxSession(HttpServletRequest httpRequest) {
- return null;
- }
-
- @Override
- public boolean checkAuthorizationHeader(HttpServletRequest httpRequest) {
- return isAuthorized;
+ if (!isAuthorized) {
+ throw new MailboxSessionCreationException(null);
+ }
+ return mock(MailboxSession.class);
}
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/62627357/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java
index c96b7a8..4a60578 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/JWTAuthenticationStrategyTest.java
@@ -70,6 +70,25 @@ public class JWTAuthenticationStrategyTest {
}
@Test
+ public void createMailboxSessionShouldThrownWhenAuthHeadersIsInvalid() throws Exception {
+ String username = "123456789";
+ String validAuthHeader = "valid";
+ String fakeAuthHeaderWithPrefix = JWTAuthenticationStrategy.AUTHORIZATION_HEADER_PREFIX + validAuthHeader;
+ MailboxSession fakeMailboxSession = mock(MailboxSession.class);
+
+ when(stubTokenVerifier.verify(validAuthHeader)).thenReturn(false);
+ when(stubTokenVerifier.extractLogin(validAuthHeader)).thenReturn(username);
+ when(mockedMailboxManager.createSystemSession(eq(username), any(Logger.class)))
+ .thenReturn(fakeMailboxSession);
+ when(mockAuthenticationExtractor.authHeaders(request))
+ .thenReturn(Stream.of(fakeAuthHeaderWithPrefix));
+
+
+ assertThatThrownBy(() -> testee.createMailboxSession(request))
+ .isExactlyInstanceOf(NoValidAuthHeaderException.class);
+ }
+
+ @Test
public void createMailboxSessionShouldReturnEmptyWhenAuthHeaderIsInvalid() throws Exception {
when(mockAuthenticationExtractor.authHeaders(request))
.thenReturn(Stream.of("bad"));
@@ -113,69 +132,4 @@ public class JWTAuthenticationStrategyTest {
MailboxSession result = testee.createMailboxSession(request);
assertThat(result).isEqualTo(fakeMailboxSession);
}
-
- @Test
- public void checkAuthorizationHeaderShouldReturnFalsewWhenAuthHeaderIsEmpty() {
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(Stream.empty());
-
- assertThat(testee.checkAuthorizationHeader(request)).isFalse();
- }
-
- @Test
- public void checkAuthorizationHeaderShouldReturnFalseWhenAuthHeaderIsInvalid() {
- String wrongAuthHeader = "invalid";
- String fakeAuthHeaderWithPrefix = JWTAuthenticationStrategy.AUTHORIZATION_HEADER_PREFIX + wrongAuthHeader;
-
- when(stubTokenVerifier.verify(wrongAuthHeader)).thenReturn(false);
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(Stream.of(fakeAuthHeaderWithPrefix));
-
- assertThat(testee.checkAuthorizationHeader(request)).isFalse();
- }
-
- @Test
- public void checkAuthorizationHeaderShouldReturnFalseWhenAuthHeadersAreInvalid() {
- String wrongAuthHeader = "invalid";
- String invalidAuthHeader = "INVALID";
-
- when(stubTokenVerifier.verify(wrongAuthHeader)).thenReturn(false);
- when(stubTokenVerifier.verify(invalidAuthHeader)).thenReturn(false);
-
- Stream<String> authHeadersStream = Stream.of(wrongAuthHeader, invalidAuthHeader)
- .map(h -> JWTAuthenticationStrategy.AUTHORIZATION_HEADER_PREFIX + h);
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(authHeadersStream);
-
- assertThat(testee.checkAuthorizationHeader(request)).isFalse();
- }
-
- @Test
- public void checkAuthorizationHeaderShouldReturnTrueWhenAuthHeaderIsValid() {
- String validAuthHeader = "valid";
- String validAuthHeaderWithPrefix = JWTAuthenticationStrategy.AUTHORIZATION_HEADER_PREFIX + validAuthHeader;
-
- when(stubTokenVerifier.verify(validAuthHeader)).thenReturn(true);
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(Stream.of(validAuthHeaderWithPrefix));
-
- assertThat(testee.checkAuthorizationHeader(request)).isTrue();
- }
-
- @Test
- public void checkAuthorizationHeaderShouldReturnTrueWhenOneAuthHeaderIsValid() {
- String dummyAuthHeader = "invalid";
- String validAuthHeader = "correct";
-
- when(stubTokenVerifier.verify(dummyAuthHeader)).thenReturn(false);
- when(stubTokenVerifier.verify(validAuthHeader)).thenReturn(true);
-
- Stream<String> authHeadersStream = Stream.of(dummyAuthHeader, validAuthHeader)
- .map(h -> JWTAuthenticationStrategy.AUTHORIZATION_HEADER_PREFIX + h);
- when(mockAuthenticationExtractor.authHeaders(request))
- .thenReturn(authHeadersStream);
-
- assertThat(testee.checkAuthorizationHeader(request)).isTrue();
- }
-
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org