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