/* * Copyright (C) 2013-2017 NTT DATA Corporation * * 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. */ package org.terasoluna.gfw.web.token.transaction; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import static org.hamcrest.CoreMatchers.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.Matchers.*; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.ui.Model; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.method.HandlerMethod; import org.terasoluna.gfw.web.token.TokenStringGenerator; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:test-context.xml" }) public class TransactionTokenInterceptorTest { @Autowired ConfigurableApplicationContext context; TransactionTokenInterceptor interceptor; MockHttpServletRequest request; MockHttpServletResponse response; @Before public void setUp() throws Exception { // prepare request object request = new MockHttpServletRequest(); request.setRequestURI("/token/first"); request.setMethod("GET"); // prepare response object response = new MockHttpServletResponse(); // set ServletRequestAttributes to RequestContextHolder ServletRequestAttributes attributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(attributes); // prepare intercepter instance interceptor = new TransactionTokenInterceptor(); } @After public void tearDown() throws Exception { } @Test public void testPreHandleIncorrectHandler() throws Exception { boolean result = interceptor.preHandle(request, response, null); assertTrue(result); } @Test public void testPreHandleWithoutTokenValidate() throws Exception { boolean result = interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("first", SampleForm.class, Model.class))); assertTrue(result); } @Test public void testPreHandleWithTokenValidate() throws Exception { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); TransactionToken inputToken = new TransactionToken("testTokenAttr", "111", "222"); tokenStore.store(inputToken); request.setParameter( TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, "testTokenAttr~111~222"); interceptor = new TransactionTokenInterceptor(new TokenStringGenerator(), new TransactionTokenInfoStore(), tokenStore); boolean result = interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("third", SampleForm.class, Model.class))); // Confirm return value assertTrue(result); // Confirm that TokenContext is stored in the request assertNotNull(request .getAttribute(TransactionTokenInterceptor.TOKEN_CONTEXT_REQUEST_ATTRIBUTE_NAME)); } @Test(expected = InvalidTransactionTokenException.class) public void testPreHandleWithTokenValidateFail() throws Exception { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); interceptor = new TransactionTokenInterceptor(new TokenStringGenerator(), new TransactionTokenInfoStore(), tokenStore); interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("third", SampleForm.class, Model.class))); } @Test public void testPreHandleTokenIsSentInHiddenFieldAtBeginPhase() throws Exception { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); TransactionToken inputToken = new TransactionToken("tokenName1", "111", "222"); tokenStore.store(inputToken); assertThat(tokenStore.getSession().getAttribute( tokenStore.createSessionAttributeName(inputToken)), is(notNullValue())); request.setParameter( TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, "tokenName1~111~222"); interceptor = new TransactionTokenInterceptor(new TokenStringGenerator(), new TransactionTokenInfoStore(), tokenStore); interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("first", SampleForm.class, Model.class))); // check if inputToken is removed assertThat(tokenStore.getSession().getAttribute( tokenStore.createSessionAttributeName(inputToken)), is(nullValue())); } @Test public void testPreHandleValidTokenOnCheck() throws Exception { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); TransactionToken inputToken = new TransactionToken("testTokenAttr", "111", "222"); tokenStore.store(inputToken); assertThat(tokenStore.getSession().getAttribute( tokenStore.createSessionAttributeName(inputToken)), is(notNullValue())); request.setParameter( TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, "testTokenAttr~111~222"); interceptor = new TransactionTokenInterceptor(new TokenStringGenerator(), new TransactionTokenInfoStore(), tokenStore); boolean result = interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("fifth", SampleForm.class, Model.class))); assertTrue(result); TransactionTokenContext transactionTokenCtx = (TransactionTokenContext) request .getAttribute(TransactionTokenInterceptor.TOKEN_CONTEXT_REQUEST_ATTRIBUTE_NAME); TransactionToken token = transactionTokenCtx.getReceivedToken(); assertNotNull(token); assertThat(token.getTokenName(), is("testTokenAttr")); assertThat(token.getTokenKey(), is("111")); assertThat(token.getTokenValue(), is("222")); } @Test public void testValidateToken01() { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); TransactionToken inputToken = new TransactionToken("tokenName1", "111", "222"); tokenStore.store(inputToken); TransactionTokenInfo tokenInfo = new TransactionTokenInfo("tokenName1", TransactionTokenType.IN); boolean result = interceptor.validateToken(inputToken, tokenStore, tokenInfo); assertTrue(result); result = interceptor.validateToken(inputToken, tokenStore, tokenInfo); assertFalse(result); } @Test public void testValidateToken02() { HttpSessionTransactionTokenStore tokenStore = mock(HttpSessionTransactionTokenStore.class); TransactionToken inputToken = new TransactionToken("tokenName1", "111", "222"); TransactionTokenInfo tokenInfo = new TransactionTokenInfo("tokenName1", TransactionTokenType.IN); // Set mock behavior when(tokenStore.getAndClear((TransactionToken) anyObject())) .thenReturn("differentValue"); boolean result = interceptor.validateToken(inputToken, tokenStore, tokenInfo); assertFalse(result); } // ---------------Constructor related--------------- @Test public void testNonParameterizedConstructor() { // Use parameterless constructor interceptor = new TransactionTokenInterceptor(); assertNotNull(interceptor); } @Test public void testIntConstructor() { // Use int constructor interceptor = new TransactionTokenInterceptor(10); assertNotNull(interceptor); } // ------------------------------ @Test public void testCreateReceivedToken() { request.setParameter( TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, "a~b~c"); TransactionToken token = interceptor.createReceivedToken(request); assertThat(token.getTokenName(), is("a")); } @Test public void testRemoveEmptyToken() { // This test case should always pass // This will ensure that neither valid/invalid token removal generates // exception try { interceptor.removeToken(new TransactionToken("")); interceptor.removeToken(new TransactionToken("a~b~c")); } catch (Exception ex) { fail(); } } @Test public void testPostHandleIncorrectHandler() throws Exception { try { interceptor.postHandle(request, response, null, null); } catch (Exception ex) { fail(); } } @Test public void testPostHandleWithRemoveToken() throws Exception { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); TransactionToken inputToken = new TransactionToken("testTokenAttr", "111", "222"); tokenStore.store(inputToken); request.setParameter( TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, "testTokenAttr~111~222"); interceptor = new TransactionTokenInterceptor(new TokenStringGenerator(), new TransactionTokenInfoStore(), tokenStore); interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("third", SampleForm.class, Model.class))); interceptor .postHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("third", SampleForm.class, Model.class)), null); // Confirm that token is removed from session assertNull(tokenStore .getSession() .getAttribute( HttpSessionTransactionTokenStore.TOKEN_HOLDER_SESSION_ATTRIBUTE_PREFIX + inputToken.getTokenName() + "~" + inputToken.getTokenKey())); } @Test public void testPostHandleWithCreateToken() throws Exception { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); TransactionToken inputToken = new TransactionToken("tokenName1", "111", "222"); tokenStore.store(inputToken); request.setParameter( TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, "tokenName1~111~222"); interceptor = new TransactionTokenInterceptor(new TokenStringGenerator(), new TransactionTokenInfoStore(), tokenStore); interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("first", SampleForm.class, Model.class))); interceptor .postHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("third", SampleForm.class, Model.class)), null); // Next token is stored in request object assertNotNull(request .getAttribute(TransactionTokenInterceptor.NEXT_TOKEN_REQUEST_ATTRIBUTE_NAME)); TransactionToken nextToken = (TransactionToken) request .getAttribute(TransactionTokenInterceptor.NEXT_TOKEN_REQUEST_ATTRIBUTE_NAME); // Confirm that next token is present in the session assertNotNull(tokenStore .getSession() .getAttribute( HttpSessionTransactionTokenStore.TOKEN_HOLDER_SESSION_ATTRIBUTE_PREFIX + nextToken.getTokenName() + "~" + nextToken.getTokenKey())); } @Test public void testPostHandleWithUpdateToken() throws Exception { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); TransactionToken inputToken = new TransactionToken("testTokenAttr", "111", "222"); tokenStore.store(inputToken); request.setParameter( TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, "testTokenAttr~111~222"); interceptor = new TransactionTokenInterceptor(new TokenStringGenerator(), new TransactionTokenInfoStore(), tokenStore); interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("second", SampleForm.class, Model.class, TransactionTokenContext.class))); interceptor .postHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("third", SampleForm.class, Model.class)), null); // Confirm that token is still present in the session assertNotNull(tokenStore .getSession() .getAttribute( HttpSessionTransactionTokenStore.TOKEN_HOLDER_SESSION_ATTRIBUTE_PREFIX + inputToken.getTokenName() + "~" + inputToken.getTokenKey())); // Next token is also stored in request object assertNotNull(request .getAttribute(TransactionTokenInterceptor.NEXT_TOKEN_REQUEST_ATTRIBUTE_NAME)); } @Test public void testPostHandleWithKeepToken() throws Exception { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); TransactionToken inputToken = new TransactionToken("testTokenAttr", "111", "222"); tokenStore.store(inputToken); request.setParameter( TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, "testTokenAttr~111~222"); interceptor = new TransactionTokenInterceptor(new TokenStringGenerator(), new TransactionTokenInfoStore(), tokenStore); interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("fifth", SampleForm.class, Model.class))); interceptor .postHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("fifth", SampleForm.class, Model.class)), null); TransactionToken nextToken = (TransactionToken) request .getAttribute(TransactionTokenInterceptor.NEXT_TOKEN_REQUEST_ATTRIBUTE_NAME); assertNotNull(nextToken); assertThat(nextToken.getTokenName(), is("testTokenAttr")); assertThat(nextToken.getTokenKey(), is("111")); assertThat(nextToken.getTokenValue(), is("222")); assertThat(tokenStore.getAndClear(nextToken), is("222")); } @Test public void testPostHandleWithNoneOperation() throws Exception { TransactionTokenContextImpl context = mock(TransactionTokenContextImpl.class); request.setAttribute( TransactionTokenInterceptor.TOKEN_CONTEXT_REQUEST_ATTRIBUTE_NAME, context); when(context.getReserveCommand()).thenReturn( TransactionTokenContextImpl.ReserveCommand.NONE); try { interceptor .postHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("third", SampleForm.class, Model.class)), null); } catch (Exception e) { fail(); } } @Test public void testAfterCompletionWithoutException() { try { interceptor.afterCompletion(request, response, null, null); } catch (Exception e) { fail(); } } @Test public void testAfterCompletionWithException() { try { HttpSessionTransactionTokenStore tokenStore = new HttpSessionTransactionTokenStore(); TransactionToken inputToken = new TransactionToken("testTokenAttr", "111", "222"); tokenStore.store(inputToken); request.setParameter( TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, "testTokenAttr~111~222"); interceptor = new TransactionTokenInterceptor(new TokenStringGenerator(), new TransactionTokenInfoStore(), tokenStore); interceptor .preHandle( request, response, new HandlerMethod(new TransactionTokenSampleController(), TransactionTokenSampleController.class .getDeclaredMethod("third", SampleForm.class, Model.class))); // Confirm that token is stored in session assertNotNull(tokenStore .getSession() .getAttribute( HttpSessionTransactionTokenStore.TOKEN_HOLDER_SESSION_ATTRIBUTE_PREFIX + inputToken.getTokenName() + "~" + inputToken.getTokenKey())); // Consider that exception has occured and call afterCompletion() // method // This call should remove the token from the store Exception ex = new InvalidTransactionTokenException(); interceptor.afterCompletion(request, response, null, ex); // Confirm that token is removed from session assertNull(tokenStore .getSession() .getAttribute( HttpSessionTransactionTokenStore.TOKEN_HOLDER_SESSION_ATTRIBUTE_PREFIX + inputToken.getTokenName() + "~" + inputToken.getTokenKey())); } catch (Exception e) { fail(); } } @Test public void testAfterCompletionWithExceptionHasNoTransactionTokenContextImpl() { try { interceptor.afterCompletion(request, response, null, new Exception()); } catch (Exception e) { fail(); } } /* * @Test public void testCreateTokenSynchronization() throws Exception { int size = 2000; Thread arrThreads[] = new * Thread[size]; for (int i = 0; i <size ; i++) { Thread thread = new Thread(new Runnable() { * @Override public void run() { try { interceptor.createToken(request, session1, tokenInfo1, generator1, tokenStore1); } * catch (Exception ex) { ex.printStackTrace(); } } }, "Thread_" + (i+1)); arrThreads[i] = thread; } for (Thread thread : * arrThreads) { try { thread.start(); thread.join(); } catch (Exception e) { // TODO Auto-generated catch block * e.printStackTrace(); } } } */ }