package de.otto.edison.authentication; import org.junit.Before; import org.junit.Test; import org.springframework.util.Base64Utils; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import static de.otto.edison.authentication.configuration.LdapProperties.ldapProperties; import static org.mockito.Mockito.*; import static org.springframework.http.HttpHeaders.AUTHORIZATION; import static org.springframework.http.HttpHeaders.WWW_AUTHENTICATE; import static org.springframework.http.HttpStatus.UNAUTHORIZED; public class LdapAuthenticationFilterTest { private static final String WHITELISTED_PATH = "/internal/health"; private LdapAuthenticationFilter testee; private HttpServletResponse response; @Before public void setUp() throws Exception { testee = new LdapAuthenticationFilter(ldapProperties("someHost", 389, "someBaseDn", "someRdnIdentifier", "/internal", WHITELISTED_PATH)); response = mock(HttpServletResponse.class); } @Test public void shouldBeUnauthenticatedIfHostIsNotConfigured() throws Exception { testee = new LdapAuthenticationFilter(ldapProperties("", 389, "someBaseDn", "someRdnIdentifier", "/internal")); assertValidRequestIsUnauthorized(); } @Test public void shouldBeUnauthenticatedIfBaseDnIsNotConfigured() throws Exception { testee = new LdapAuthenticationFilter(ldapProperties("someHost", 389, "", "someRdnIdentifier", "/internal")); assertValidRequestIsUnauthorized(); } @Test public void shouldBeUnauthenticatedIfRdnIdentifierIsNotConfigured() throws Exception { testee = new LdapAuthenticationFilter(ldapProperties("someHost", 389, "someBaseDn", "", "/internal")); assertValidRequestIsUnauthorized(); } @Test public void shouldBeUnauthenticatedIfAuthorizationHeaderIsMissing() throws Exception { testee.doFilter(requestWithoutAuthorizationHeader(), response, mock(FilterChain.class)); assertUnauthorized(); } @Test public void shouldBeUnauthenticatedIfLdapConnectionFails() throws Exception { testee.doFilter(requestWithAuthorizationHeader(), response, mock(FilterChain.class)); assertUnauthorized(); } @Test public void shouldNotApplyFilterToWhitelistedEndpoint() throws Exception { HttpServletRequest request = requestWithoutAuthorizationHeader(); when(request.getServletPath()).thenReturn(WHITELISTED_PATH + "/etc"); FilterChain filterChain = mock(FilterChain.class); testee.doFilter(request, response, filterChain); verify(filterChain).doFilter(request, response); } private HttpServletRequest requestWithoutAuthorizationHeader() { HttpServletRequest request = mock(HttpServletRequest.class); when(request.getServletPath()).thenReturn("/internal"); return request; } private HttpServletRequest requestWithAuthorizationHeader() { HttpServletRequest request = mock(HttpServletRequest.class); when(request.getHeader(AUTHORIZATION)).thenReturn("Basic " + Base64Utils.encodeToString("someUsername:somePassword".getBytes())); when(request.getServletPath()).thenReturn("/internal"); return request; } private void assertValidRequestIsUnauthorized() throws IOException, ServletException { testee.doFilter(requestWithAuthorizationHeader(), response, mock(FilterChain.class)); assertUnauthorized(); } private void assertUnauthorized() { verify(response).setStatus(UNAUTHORIZED.value()); verify(response).addHeader(WWW_AUTHENTICATE, "Basic realm=Authorization Required"); } }