Author: matthieu
Date: Fri Dec 11 10:07:52 2015
New Revision: 1719319

URL: http://svn.apache.org/viewvc?rev=1719319&view=rev
Log:
JAMES-1644 GET to Refetch URL endpoints and Check Authentication header by 
servlet filter

Added:
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/BypassOnPostFilter.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/EndPointsResponse.java
    
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
    
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/BypassOnPostFilterTest.java
Modified:
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/api/AccessTokenManager.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/AccessTokenManagerImpl.java
    
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
    
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/AccessTokenManagerImplTest.java

Added: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java?rev=1719319&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationFilter.java
 Fri Dec 11 10:07:52 2015
@@ -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;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.james.jmap.api.AccessTokenManager;
+import org.apache.james.jmap.api.access.AccessToken;
+
+public class AuthenticationFilter implements Filter {
+    
+    private AccessTokenManager accessTokenManager;
+
+    public AuthenticationFilter(AccessTokenManager accessTokenManager) {
+        this.accessTokenManager = accessTokenManager;
+    }
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest httpRequest = (HttpServletRequest)request;
+        Optional<String> authHeader = 
Optional.ofNullable(httpRequest.getHeader("Authorization"));
+        if (!checkAuthorizationHeader(authHeader)) {
+            
((HttpServletResponse)response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            return;
+        }
+        chain.doFilter(request, response);
+    }
+
+    private boolean checkAuthorizationHeader(Optional<String> authHeader) 
throws IOException {
+        return authHeader
+                .map(x -> 
accessTokenManager.isValid(AccessToken.fromString(x)))
+                .orElse(false);
+    }
+
+    @Override
+    public void destroy() {
+    }
+
+}

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java?rev=1719319&r1=1719318&r2=1719319&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java
 Fri Dec 11 10:07:52 2015
@@ -35,6 +35,7 @@ import org.apache.james.jmap.model.Acces
 import org.apache.james.jmap.model.AccessTokenResponse;
 import org.apache.james.jmap.model.ContinuationTokenRequest;
 import org.apache.james.jmap.model.ContinuationTokenResponse;
+import org.apache.james.jmap.model.EndPointsResponse;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.slf4j.Logger;
@@ -87,6 +88,11 @@ public class AuthenticationServlet exten
             resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
         }
     }
+    
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
+        returnEndPointsResponse(resp);
+    }
 
     private Object deserialize(HttpServletRequest req) throws 
BadRequestException {
         Object request;
@@ -168,6 +174,17 @@ public class AuthenticationServlet exten
             .build();
         mapper.writeValue(resp.getOutputStream(), response);
     }
+
+    private void returnEndPointsResponse(HttpServletResponse resp) throws 
IOException {
+        resp.setContentType(JSON_CONTENT_TYPE_UTF8);
+        resp.setStatus(HttpServletResponse.SC_OK);
+        EndPointsResponse response = EndPointsResponse
+            .builder()
+            .api("/api")
+            // TODO Send other API endpoints
+            .build();
+        mapper.writeValue(resp.getOutputStream(), response);
+    }
 
     private void returnUnauthorizedResponse(HttpServletResponse resp) throws 
IOException {
         resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);

Added: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/BypassOnPostFilter.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/BypassOnPostFilter.java?rev=1719319&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/BypassOnPostFilter.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/BypassOnPostFilter.java
 Fri Dec 11 10:07:52 2015
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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.io.IOException;
+
+import javax.inject.Inject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+public class BypassOnPostFilter implements Filter {
+    
+    private Filter nestedFilter;
+
+    @Inject
+    public BypassOnPostFilter(AuthenticationFilter nestedFilter) {
+        this.nestedFilter = nestedFilter;
+    }
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest httpRequest = (HttpServletRequest)request;
+        if ("POST".equals(httpRequest.getMethod())) {
+            chain.doFilter(request, response);
+        } else {
+            nestedFilter.doFilter(httpRequest, response, chain);
+        }
+    }
+
+    @Override
+    public void destroy() {
+    }
+
+}

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/api/AccessTokenManager.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/api/AccessTokenManager.java?rev=1719319&r1=1719318&r2=1719319&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/api/AccessTokenManager.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/api/AccessTokenManager.java
 Fri Dec 11 10:07:52 2015
@@ -27,5 +27,7 @@ public interface AccessTokenManager {
     AccessToken grantAccessToken(String username);
 
     String getUsernameFromToken(AccessToken token) throws InvalidAccessToken;
+    
+    boolean isValid(AccessToken token);
 
 }

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/AccessTokenManagerImpl.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/AccessTokenManagerImpl.java?rev=1719319&r1=1719318&r2=1719319&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/AccessTokenManagerImpl.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/AccessTokenManagerImpl.java
 Fri Dec 11 10:07:52 2015
@@ -46,5 +46,15 @@ public class AccessTokenManagerImpl impl
     public String getUsernameFromToken(AccessToken token) throws 
InvalidAccessToken {
         return accessTokenRepository.getUsernameFromToken(token);
     }
+    
+    @Override
+    public boolean isValid(AccessToken token) throws InvalidAccessToken {
+        try {
+            getUsernameFromToken(token);
+            return true;
+        } catch (InvalidAccessToken e) {
+            return false;
+        }
+    }
 
 }

Added: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/EndPointsResponse.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/EndPointsResponse.java?rev=1719319&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/EndPointsResponse.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/EndPointsResponse.java
 Fri Dec 11 10:07:52 2015
@@ -0,0 +1,89 @@
+/****************************************************************
+ * 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.model;
+
+public class EndPointsResponse {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+        private String api;
+        private String eventSource;
+        private String upload;
+        private String download;
+
+        private Builder() {
+        }
+
+        public Builder api(String api) {
+            this.api = api;
+            return this;
+        }
+
+        public Builder eventSource(String eventSource) {
+            this.eventSource = eventSource;
+            return this;
+        }
+
+        public Builder upload(String upload) {
+            this.upload = upload;
+            return this;
+        }
+
+        public Builder download(String download) {
+            this.download = download;
+            return this;
+        }
+
+        public EndPointsResponse build() {
+            return new EndPointsResponse(api, eventSource, upload, download);
+        }
+    }
+
+    private final String api;
+    private final String eventSource;
+    private final String upload;
+    private final String download;
+
+    private EndPointsResponse(String api, String eventSource, String upload, 
String download) {
+        this.api = api;
+        this.eventSource = eventSource;
+        this.upload = upload;
+        this.download = download;
+    }
+
+    public String getApi() {
+        return api;
+    }
+
+    public String getEventSource() {
+        return eventSource;
+    }
+
+    public String getUpload() {
+        return upload;
+    }
+
+    public String getDownload() {
+        return download;
+    }
+
+}
\ No newline at end of file

Added: 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java?rev=1719319&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/AuthenticationFilterTest.java
 Fri Dec 11 10:07:52 2015
@@ -0,0 +1,86 @@
+/****************************************************************
+ * 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.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.james.jmap.api.AccessTokenManager;
+import org.apache.james.jmap.api.access.AccessToken;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AuthenticationFilterTest {
+    private static final String TOKEN = "df991d2a-1c5a-4910-a90f-808b6eda133e";
+
+    private HttpServletRequest mockedRequest;
+    private HttpServletResponse mockedResponse;
+    private AccessTokenManager mockedAccessTokenManager;
+    private AuthenticationFilter tested;
+    private FilterChain filterChain;
+    
+    @Before
+    public void setup() throws Exception {
+        mockedRequest = mock(HttpServletRequest.class);
+        mockedResponse = mock(HttpServletResponse.class);
+        mockedAccessTokenManager = mock(AccessTokenManager.class);
+        tested = new AuthenticationFilter(mockedAccessTokenManager);
+        filterChain = mock(FilterChain.class);
+    }
+    
+    @Test
+    public void filterShouldReturnUnauthorizedOnNullAuthorizationHeader() 
throws Exception {
+        when(mockedRequest.getHeader("Authorization"))
+            .thenReturn(null);
+        
+        tested.doFilter(mockedRequest, mockedResponse, filterChain);
+        
+        verify(mockedResponse).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+    }
+    
+    @Test
+    public void filterShouldReturnUnauthorizedOnInvalidAuthorizationHeader() 
throws Exception {
+        when(mockedRequest.getHeader("Authorization"))
+            .thenReturn(TOKEN);
+        when(mockedAccessTokenManager.isValid(AccessToken.fromString(TOKEN)))
+            .thenReturn(false);
+        
+        tested.doFilter(mockedRequest, mockedResponse, filterChain);
+        
+        verify(mockedResponse).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+    }
+    
+    @Test
+    public void filterShouldChainOnValidAuthorizationHeader() throws Exception 
{
+        when(mockedRequest.getHeader("Authorization"))
+            .thenReturn(TOKEN);
+        when(mockedAccessTokenManager.isValid(AccessToken.fromString(TOKEN)))
+            .thenReturn(true);
+        
+        tested.doFilter(mockedRequest, mockedResponse, filterChain);
+        
+        verify(filterChain).doFilter(mockedRequest, mockedResponse);
+    }
+    
+}

Added: 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/BypassOnPostFilterTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/BypassOnPostFilterTest.java?rev=1719319&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/BypassOnPostFilterTest.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/BypassOnPostFilterTest.java
 Fri Dec 11 10:07:52 2015
@@ -0,0 +1,87 @@
+/****************************************************************
+ * 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.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class BypassOnPostFilterTest {
+
+    private HttpServletRequest mockedRequest;
+    private AuthenticationFilter nestedFilter;
+    private BypassOnPostFilter tested;
+    private FilterChain filterChain;
+    
+    @Before
+    public void setup() throws Exception {
+        mockedRequest = mock(HttpServletRequest.class);
+        nestedFilter = mock(AuthenticationFilter.class);
+        tested = new BypassOnPostFilter(nestedFilter);
+        filterChain = mock(FilterChain.class);
+    }
+    
+    @Test
+    public void filterShouldCallNestedFilterOnGet() throws Exception {
+        when(mockedRequest.getMethod())
+            .thenReturn("GET");
+        
+        tested.doFilter(mockedRequest, null, filterChain);
+        
+        verify(nestedFilter).doFilter(mockedRequest, null, filterChain);
+    }
+    
+    @Test
+    public void filterShouldNotCallDirectlyChainOnGet() throws Exception {
+        when(mockedRequest.getMethod())
+            .thenReturn("GET");
+        
+        tested.doFilter(mockedRequest, null, filterChain);
+        
+        verify(filterChain, never()).doFilter(mockedRequest, null);
+    }
+    
+    @Test
+    public void filterShouldNotCallNestedFilterOnPost() throws Exception {
+        when(mockedRequest.getMethod())
+            .thenReturn("POST");
+        
+        tested.doFilter(mockedRequest, null, filterChain);
+        
+        verify(nestedFilter, never()).doFilter(mockedRequest, null, 
filterChain);
+    }
+    
+    @Test
+    public void filterShouldCallChainOnPost() throws Exception {
+        when(mockedRequest.getMethod())
+            .thenReturn("POST");
+        
+        tested.doFilter(mockedRequest, null, filterChain);
+        
+        verify(filterChain).doFilter(mockedRequest, null);
+    }
+    
+}

Modified: 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java?rev=1719319&r1=1719318&r2=1719319&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
 Fri Dec 11 10:07:52 2015
@@ -29,11 +29,15 @@ import static org.mockito.Mockito.when;
 
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.UUID;
+
+import javax.servlet.Filter;
 
 import org.apache.james.http.jetty.Configuration;
 import org.apache.james.http.jetty.JettyHttpServer;
 import org.apache.james.jmap.api.AccessTokenManager;
 import org.apache.james.jmap.api.ContinuationTokenManager;
+import org.apache.james.jmap.api.access.AccessToken;
 import org.apache.james.jmap.crypto.AccessTokenManagerImpl;
 import org.apache.james.jmap.crypto.JamesSignatureHandlerProvider;
 import org.apache.james.jmap.crypto.SignedContinuationTokenManager;
@@ -70,14 +74,19 @@ public class JMAPAuthenticationTest {
         continuationTokenManager = new SignedContinuationTokenManager(new 
JamesSignatureHandlerProvider().provide(), mockedZonedDateTimeProvider);
         
         AuthenticationServlet authenticationServlet = new 
AuthenticationServlet(mockedUsersRepository, continuationTokenManager, 
accessTokenManager);
+        AuthenticationFilter authenticationFilter = new 
AuthenticationFilter(accessTokenManager);
+        Filter getAuthenticationFilter = new 
BypassOnPostFilter(authenticationFilter);
         
         server = JettyHttpServer.create(
                 Configuration.builder()
+                .filter("/*")
+                .with(getAuthenticationFilter)
                 .serve("/*")
                 .with(authenticationServlet)
                 .randomPort()
                 .build());
 
+        
         server.start();
         RestAssured.port = server.getPort();
         RestAssured.config = 
newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8));
@@ -217,15 +226,7 @@ public class JMAPAuthenticationTest {
         when(mockedZonedDateTimeProvider.provide())
             .thenReturn(oldDate);
 
-        String continuationToken =
-                with()
-                    .contentType(ContentType.JSON)
-                    .accept(ContentType.JSON)
-                    .body("{\"username\": \"[email protected]\", \"clientName\": 
\"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", \"deviceName\": \"Joe 
Blogg’s iPhone\"}")
-                .post("/authentication")
-                    .body()
-                    .path("continuationToken")
-                    .toString();
+        String continuationToken = fromGoodContinuationTokenRequest();
 
         given()
             .contentType(ContentType.JSON)
@@ -242,15 +243,7 @@ public class JMAPAuthenticationTest {
         when(mockedZonedDateTimeProvider.provide())
             .thenReturn(oldDate);
 
-        String continuationToken =
-                with()
-                    .contentType(ContentType.JSON)
-                    .accept(ContentType.JSON)
-                    .body("{\"username\": \"[email protected]\", \"clientName\": 
\"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", \"deviceName\": \"Joe 
Blogg’s iPhone\"}")
-                .post("/authentication")
-                    .body()
-                    .path("continuationToken")
-                    .toString();
+        String continuationToken = fromGoodContinuationTokenRequest();
         
         when(mockedUsersRepository.test("[email protected]", "password"))
             .thenReturn(true);
@@ -272,15 +265,7 @@ public class JMAPAuthenticationTest {
         when(mockedZonedDateTimeProvider.provide())
             .thenReturn(oldDate);
 
-        String continuationToken =
-                with()
-                    .contentType(ContentType.JSON)
-                    .accept(ContentType.JSON)
-                    .body("{\"username\": \"[email protected]\", \"clientName\": 
\"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", \"deviceName\": \"Joe 
Blogg’s iPhone\"}")
-                .post("/authentication")
-                    .body()
-                    .path("continuationToken")
-                    .toString();
+        String continuationToken = fromGoodContinuationTokenRequest();
 
         when(mockedUsersRepository.test("[email protected]", "password"))
             .thenThrow(new UsersRepositoryException("test"));
@@ -300,15 +285,7 @@ public class JMAPAuthenticationTest {
         when(mockedZonedDateTimeProvider.provide())
             .thenReturn(oldDate);
 
-        String continuationToken =
-                with()
-                    .contentType(ContentType.JSON)
-                    .accept(ContentType.JSON)
-                    .body("{\"username\": \"[email protected]\", \"clientName\": 
\"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", \"deviceName\": \"Joe 
Blogg’s iPhone\"}")
-                .post("/authentication")
-                    .body()
-                    .path("continuationToken")
-                    .toString();
+        String continuationToken = fromGoodContinuationTokenRequest();
 
         when(mockedUsersRepository.test("[email protected]", "password"))
             .thenReturn(true);
@@ -330,15 +307,7 @@ public class JMAPAuthenticationTest {
         when(mockedZonedDateTimeProvider.provide())
             .thenReturn(oldDate);
 
-        String continuationToken =
-                with()
-                    .contentType(ContentType.JSON)
-                    .accept(ContentType.JSON)
-                    .body("{\"username\": \"[email protected]\", \"clientName\": 
\"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", \"deviceName\": \"Joe 
Blogg’s iPhone\"}")
-                .post("/authentication")
-                    .body()
-                    .path("continuationToken")
-                    .toString();
+        String continuationToken = fromGoodContinuationTokenRequest();
 
         when(mockedUsersRepository.test("[email protected]", "password"))
             .thenReturn(true);
@@ -354,5 +323,76 @@ public class JMAPAuthenticationTest {
         .then()
             .body("accessToken", isA(String.class));
     }
+    
+    @Test
+    public void getMustReturnUnauthorizedWithoutAuthroizationHeader() throws 
Exception {
+        given()
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(401);
+    }
+
+    @Test
+    public void getMustReturnUnauthorizedWithoutAValidAuthroizationHeader() 
throws Exception {
+        given()
+            .header("Authorization", UUID.randomUUID())
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(401);
+    }
+
+    @Test
+    public void getMustReturnEndpointsWhenValidAuthorizationHeader() throws 
Exception {
+        AccessToken token = accessTokenManager.grantAccessToken("username");
+        given()
+            .header("Authorization", token.serialize())
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(200)
+            .body("api", isA(String.class));
+    }
+
+    @Test
+    public void getMustReturnEndpointsWhenCorrectAuthentication() throws 
Exception {
+        when(mockedZonedDateTimeProvider.provide())
+            .thenReturn(oldDate);
+
+        String continuationToken = fromGoodContinuationTokenRequest();
+    
+        when(mockedUsersRepository.test("[email protected]", "password"))
+            .thenReturn(true);
+        when(mockedZonedDateTimeProvider.provide())
+            .thenReturn(newDate);
+    
+        String accessToken = with()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"token\": \"" + continuationToken + "\", \"method\": 
\"password\", \"password\": \"password\"}")
+        .post("/authentication")
+            .path("accessToken")
+            .toString();
+    
+        given()
+            .header("Authorization", accessToken)
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(200)
+            .body("api", isA(String.class));
+    }
+
+    private String fromGoodContinuationTokenRequest() {
+        return with()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"username\": \"[email protected]\", \"clientName\": 
\"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", \"deviceName\": \"Joe 
Blogg’s iPhone\"}")
+        .post("/authentication")
+            .body()
+            .path("continuationToken")
+            .toString();
+    }
 
 }

Modified: 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/AccessTokenManagerImplTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/AccessTokenManagerImplTest.java?rev=1719319&r1=1719318&r2=1719319&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/AccessTokenManagerImplTest.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/AccessTokenManagerImplTest.java
 Fri Dec 11 10:07:52 2015
@@ -55,6 +55,11 @@ public class AccessTokenManagerImplTest
         
assertThat(accessTokenRepository.getUsernameFromToken(token)).isEqualTo("username");
     }
     
+    @Test(expected=NullPointerException.class)
+    public void getUsernameShouldThrowWhenNullToken() throws Exception {
+        accessTokenManager.getUsernameFromToken(null);
+    }
+
     @Test(expected=InvalidAccessToken.class)
     public void getUsernameShouldThrowWhenUnknownToken() throws Exception {
         accessTokenManager.getUsernameFromToken(AccessToken.generate());
@@ -71,5 +76,26 @@ public class AccessTokenManagerImplTest
         AccessToken token = accessTokenManager.grantAccessToken("username");
         
assertThat(accessTokenManager.getUsernameFromToken(token)).isEqualTo("username");
     }
-
+    
+    @Test(expected=NullPointerException.class)
+    public void isValidShouldThrowOnNullToken() throws Exception {
+        accessTokenManager.isValid(null);
+    }
+    
+    @Test
+    public void isValidShouldReturnFalseOnUnknownToken() throws Exception {
+        
assertThat(accessTokenManager.isValid(AccessToken.generate())).isFalse();
+    }
+    
+    @Test
+    public void isValidShouldReturnFalseWhenOtherToken() throws Exception {
+        accessTokenManager.grantAccessToken("username");
+        
assertThat(accessTokenManager.isValid(AccessToken.generate())).isFalse();
+    }
+    
+    @Test
+    public void isValidShouldReturnTrueWhenValidToken() throws Exception {
+        AccessToken accessToken = 
accessTokenManager.grantAccessToken("username");
+        assertThat(accessTokenManager.isValid(accessToken)).isTrue();
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to