From 981d203723f7bbdfa887dffa51fbf7a8a59289f4 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 23 Jun 2016 14:06:03 +0200 Subject: [PATCH] added request uri to mdc logging context --- scm-webapp/pom.xml | 6 + .../main/java/sonia/scm/filter/MDCFilter.java | 16 ++- .../java/sonia/scm/filter/MDCFilterTest.java | 128 ++++++++++++++++++ .../test/resources/sonia/scm/shiro-001.ini | 6 + 4 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 scm-webapp/src/test/java/sonia/scm/filter/MDCFilterTest.java create mode 100644 scm-webapp/src/test/resources/sonia/scm/shiro-001.ini diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index b30833a968..c7218797eb 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -348,6 +348,12 @@ test + + com.github.sdorra + shiro-unit + 1.0.0 + + diff --git a/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java b/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java index 6630543bc3..5c14269ffb 100644 --- a/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java @@ -33,6 +33,7 @@ package sonia.scm.filter; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.annotations.VisibleForTesting; import com.google.inject.Singleton; import org.apache.shiro.SecurityUtils; @@ -61,13 +62,20 @@ public class MDCFilter extends HttpFilter { /** Field description */ - private static final String MDC_CLIEN_HOST = "client_host"; + @VisibleForTesting + static final String MDC_CLIEN_HOST = "client_host"; /** Field description */ - private static final String MDC_CLIEN_IP = "client_ip"; + @VisibleForTesting + static final String MDC_CLIEN_IP = "client_ip"; + + /** url of the current request */ + @VisibleForTesting + static final String MDC_REQUEST_URI = "request_uri"; /** Field description */ - private static final String MDC_USERNAME = "username"; + @VisibleForTesting + static final String MDC_USERNAME = "username"; //~--- methods -------------------------------------------------------------- @@ -90,6 +98,7 @@ public class MDCFilter extends HttpFilter MDC.put(MDC_USERNAME, getUsername()); MDC.put(MDC_CLIEN_IP, request.getRemoteAddr()); MDC.put(MDC_CLIEN_HOST, request.getRemoteHost()); + MDC.put(MDC_REQUEST_URI, request.getRequestURI()); try { @@ -100,6 +109,7 @@ public class MDCFilter extends HttpFilter MDC.remove(MDC_USERNAME); MDC.remove(MDC_CLIEN_IP); MDC.remove(MDC_CLIEN_HOST); + MDC.remove(MDC_REQUEST_URI); } } diff --git a/scm-webapp/src/test/java/sonia/scm/filter/MDCFilterTest.java b/scm-webapp/src/test/java/sonia/scm/filter/MDCFilterTest.java new file mode 100644 index 0000000000..b5e1753c52 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/filter/MDCFilterTest.java @@ -0,0 +1,128 @@ +/*** + * Copyright (c) 2015, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * https://bitbucket.org/sdorra/scm-manager + * + */ + +package sonia.scm.filter; + +import com.github.sdorra.shiro.ShiroRule; +import com.github.sdorra.shiro.SubjectAware; +import java.io.IOException; +import java.util.Map; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.junit.Test; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; +import org.junit.Rule; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.slf4j.MDC; +import sonia.scm.AbstractTestBase; + +/** + * Unit tests for {@link MDCFilter}. + * + * @author Sebastian Sdorra + */ +@RunWith(MockitoJUnitRunner.class) +public class MDCFilterTest extends AbstractTestBase { + + @Rule + public ShiroRule shiro = new ShiroRule(); + + @Mock + private HttpServletRequest request; + + @Mock + private HttpServletResponse response; + + private final MDCFilter filter = new MDCFilter(); + + /** + * Tests {@link MDCFilter#doFilter(HttpServletRequest, HttpServletResponse, FilterChain)}. + * + * @throws IOException + * @throws ServletException + */ + @Test + @SubjectAware( + username = "trillian", + password = "secret", + configuration = "classpath:sonia/scm/shiro-001.ini" + ) + public void testDoFilter() throws IOException, ServletException + { + when(request.getRequestURI()).thenReturn("api/v1/repositories"); + when(request.getRemoteAddr()).thenReturn("127.0.0.1"); + when(request.getRemoteHost()).thenReturn("localhost"); + + MDCCapturingFilterChain chain = new MDCCapturingFilterChain(); + filter.doFilter(request, response, chain); + + assertNotNull(chain.ctx); + assertEquals("trillian", chain.ctx.get(MDCFilter.MDC_USERNAME)); + assertEquals("api/v1/repositories", chain.ctx.get(MDCFilter.MDC_REQUEST_URI)); + assertEquals("127.0.0.1", chain.ctx.get(MDCFilter.MDC_CLIEN_IP)); + assertEquals("localhost", chain.ctx.get(MDCFilter.MDC_CLIEN_HOST)); + } + + /** + * Tests {@link MDCFilter#doFilter(HttpServletRequest, HttpServletResponse, FilterChain)} as anonymous user. + * + * @throws IOException + * @throws ServletException + */ + @Test + @SubjectAware + public void testDoFilterAsAnonymous() throws IOException, ServletException { + MDCCapturingFilterChain chain = new MDCCapturingFilterChain(); + filter.doFilter(request, response, chain); + + assertNotNull(chain.ctx); + assertEquals("anonymous", chain.ctx.get(MDCFilter.MDC_USERNAME)); + } + + private static class MDCCapturingFilterChain implements FilterChain { + + private Map ctx; + + @Override + public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { + this.ctx = MDC.getCopyOfContextMap(); + } + + } + +} \ No newline at end of file diff --git a/scm-webapp/src/test/resources/sonia/scm/shiro-001.ini b/scm-webapp/src/test/resources/sonia/scm/shiro-001.ini new file mode 100644 index 0000000000..0202162d00 --- /dev/null +++ b/scm-webapp/src/test/resources/sonia/scm/shiro-001.ini @@ -0,0 +1,6 @@ +[users] +trillian = secret, user + +[roles] +admin = * +user = something:*