/*************************GO-LICENSE-START*********************************
* Copyright 2015 ThoughtWorks, Inc.
*
* Licensed 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.
*************************GO-LICENSE-END***********************************/
package com.thoughtworks.go.server.web;
import com.thoughtworks.go.server.service.BackupService;
import com.thoughtworks.go.util.SystemEnvironment;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.*;
import org.springframework.security.util.FilterChainProxy;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:WEB-INF/applicationContext-global.xml",
"classpath:WEB-INF/applicationContext-dataLocalAccess.xml",
"classpath:WEB-INF/applicationContext-acegi-security.xml"
})
public class ApiSessionFilterIntegrationTest {
@Autowired
FilterChainProxy filterChainProxy;
@Autowired
SystemEnvironment systemEnvironment;
private DelegatingFilterProxy proxy;
private MockServletContext servletContext;
@Before
public void setUp() throws Exception {
WebApplicationContext wac = mock(WebApplicationContext.class);
when(wac.getBean("filterChainProxy", javax.servlet.Filter.class)).thenReturn(filterChainProxy);
when(wac.getBean("backupService")).thenReturn(mock(BackupService.class));
filterChainProxy.init(new MockFilterConfig());
servletContext = new MockServletContext();
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
proxy = new DelegatingFilterProxy("filterChainProxy", wac);
proxy.setServletContext(servletContext);
}
@Test
public void apiRequestsShouldHaveShortLivedSessions() throws Exception {
assertShortLivedSessionFor(requestFor("/api/support"));
assertShortLivedSessionFor(requestFor("/api/pipelines/my-pipeline-1/stages.xml"));
}
@Test
public void cctrayRequestsShouldHaveShortLivedSessions() throws Exception {
assertShortLivedSessionFor(requestFor("/cctray.xml"));
}
@Test
public void idleTimeOfARequestWhichAlreadyHasASessionShouldNotBeShortened() throws Exception {
HttpServletRequest apiRequestWhichHasSession = requestFor("/api/pipelines/my-pipeline-1/stages.xml");
apiRequestWhichHasSession.getSession(true);
assertLongLivedSessionFor(apiRequestWhichHasSession);
}
@Test
public void nonApiRequestsShouldHaveLongLivedSession() throws Exception {
assertLongLivedSessionFor(requestFor("/"));
assertLongLivedSessionFor(requestFor("/home"));
assertLongLivedSessionFor(requestFor("/pipelines/my-pipeline-1/390/my-stage-1/1"));
assertLongLivedSessionFor(requestFor("/something-else"));
assertLongLivedSessionFor(requestFor("/server/messages.json"));
assertLongLivedSessionFor(requestFor("/pipelines.json"));
assertLongLivedSessionFor(requestFor("/assets/g9/stage_bar_cancelled_icon-d22d661b3cb1b4bfbb17a2072aff9cb4.png"));
}
private void assertShortLivedSessionFor(HttpServletRequest request) throws ServletException, IOException {
/* Short-lived. Non-zero. */
assertThat(getSessionIdleTimeFor(request), is(systemEnvironment.get(SystemEnvironment.API_REQUEST_IDLE_TIMEOUT_IN_SECONDS)));
}
private void assertLongLivedSessionFor(HttpServletRequest request) throws ServletException, IOException {
/* Zero because there is no session level timeout. It is the default. At web service level. */
assertThat(getSessionIdleTimeFor(request), is(0));
}
private int getSessionIdleTimeFor(HttpServletRequest request) throws ServletException, IOException {
proxy.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
return request.getSession(false).getMaxInactiveInterval();
}
private HttpServletRequest requestFor(String requestPath) {
MockHttpServletRequest request = new MockHttpServletRequest(servletContext, "GET", "/go/");
request.setPathInfo(requestPath);
return request;
}
}