diff --git a/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java b/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java index e58945a346..973b3af4cb 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java @@ -1,7 +1,6 @@ package sonia.scm.web.filter; import sonia.scm.Priority; -import sonia.scm.PushStateDispatcher; import sonia.scm.config.ScmConfiguration; import sonia.scm.filter.Filters; import sonia.scm.filter.WebElement; @@ -12,6 +11,8 @@ import sonia.scm.web.WebTokenGenerator; import sonia.scm.web.protocol.HttpProtocolServlet; import javax.inject.Inject; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -21,25 +22,23 @@ import java.util.Set; @WebElement(value = HttpProtocolServlet.PATTERN) public class HttpProtocolServletAuthenticationFilter extends AuthenticationFilter { - private final PushStateDispatcher dispatcher; private final UserAgentParser userAgentParser; @Inject public HttpProtocolServletAuthenticationFilter( ScmConfiguration configuration, Set tokenGenerators, - PushStateDispatcher dispatcher, UserAgentParser userAgentParser) { super(configuration, tokenGenerators); - this.dispatcher = dispatcher; this.userAgentParser = userAgentParser; } @Override - protected void sendUnauthorizedError(HttpServletRequest request, HttpServletResponse response) throws IOException { + protected void handleUnauthorized(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { UserAgent userAgent = userAgentParser.parse(request); if (userAgent.isBrowser()) { - dispatcher.dispatch(request, response, request.getRequestURI()); + // we can proceed the filter chain because the HttpProtocolServlet will render the ui if the client is a browser + chain.doFilter(request, response); } else { HttpUtil.sendUnauthorized(request, response); } diff --git a/scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java b/scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java new file mode 100644 index 0000000000..ff493e2b84 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java @@ -0,0 +1,72 @@ +package sonia.scm.web.filter; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import sonia.scm.config.ScmConfiguration; +import sonia.scm.util.HttpUtil; +import sonia.scm.web.UserAgent; +import sonia.scm.web.UserAgentParser; +import sonia.scm.web.WebTokenGenerator; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class HttpProtocolServletAuthenticationFilterTest { + + private ScmConfiguration configuration = new ScmConfiguration(); + + private Set tokenGenerators = Collections.emptySet(); + + @Mock + private UserAgentParser userAgentParser; + + private HttpProtocolServletAuthenticationFilter authenticationFilter; + + @Mock + private HttpServletRequest request; + + @Mock + private HttpServletResponse response; + + @Mock + private FilterChain filterChain; + + private UserAgent nonBrowser = UserAgent.builder("i'm not a browser").browser(false).build(); + private UserAgent browser = UserAgent.builder("i am a browser").browser(true).build(); + + @BeforeEach + void setUpObjectUnderTest() { + authenticationFilter = new HttpProtocolServletAuthenticationFilter(configuration, tokenGenerators, userAgentParser); + } + + @Test + void shouldSendUnauthorized() throws IOException, ServletException { + when(userAgentParser.parse(request)).thenReturn(nonBrowser); + + authenticationFilter.handleUnauthorized(request, response, filterChain); + + verify(response).sendError(HttpServletResponse.SC_UNAUTHORIZED, HttpUtil.STATUS_UNAUTHORIZED_MESSAGE); + } + + @Test + void shouldCallFilterChain() throws IOException, ServletException { + when(userAgentParser.parse(request)).thenReturn(browser); + + authenticationFilter.handleUnauthorized(request, response, filterChain); + + verify(filterChain).doFilter(request, response); + } + +}