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 <adup...@linagora.com> Authored: Fri Jul 1 14:22:56 2016 +0200 Committer: Antoine Duprat <adup...@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-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org