package org.pac4j.http.client.indirect; import org.junit.Test; import org.pac4j.core.context.HttpConstants; import org.pac4j.core.context.MockWebContext; import org.pac4j.core.exception.HttpAction; import org.pac4j.core.exception.TechnicalException; import org.pac4j.core.util.TestsConstants; import org.pac4j.core.util.TestsHelper; import org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator; import org.pac4j.core.credentials.UsernamePasswordCredentials; import java.io.UnsupportedEncodingException; import java.util.Base64; import static org.junit.Assert.*; /** * This class tests the {@link IndirectBasicAuthClient} class. * * @author Jerome Leleu * @since 1.4.0 */ public final class IndirectBasicAuthClientTests implements TestsConstants { @Test public void testMissingUsernamePasswordAuthenticator() { final IndirectBasicAuthClient basicAuthClient = new IndirectBasicAuthClient(NAME, null); basicAuthClient.setCallbackUrl(CALLBACK_URL); TestsHelper.expectException(() -> basicAuthClient.getCredentials(MockWebContext.create()), TechnicalException.class, "authenticator cannot be null"); } @Test public void testMissingProfileCreator() { final IndirectBasicAuthClient basicAuthClient = new IndirectBasicAuthClient(NAME, new SimpleTestUsernamePasswordAuthenticator()); basicAuthClient.setCallbackUrl(CALLBACK_URL); basicAuthClient.setProfileCreator(null); TestsHelper.expectException(() -> basicAuthClient.getUserProfile(new UsernamePasswordCredentials(USERNAME, PASSWORD, CLIENT_NAME), MockWebContext.create()), TechnicalException.class, "profileCreator cannot be null"); } @Test public void testMissingRealm() { final IndirectBasicAuthClient basicAuthClient = new IndirectBasicAuthClient(null, new SimpleTestUsernamePasswordAuthenticator()); basicAuthClient.setCallbackUrl(CALLBACK_URL); TestsHelper.initShouldFail(basicAuthClient, "realmName cannot be blank"); } @Test public void testHasDefaultProfileCreator() { final IndirectBasicAuthClient basicAuthClient = new IndirectBasicAuthClient(new SimpleTestUsernamePasswordAuthenticator()); basicAuthClient.setCallbackUrl(CALLBACK_URL); basicAuthClient.init(null); } @Test public void testMissingLoginUrl() { final IndirectBasicAuthClient basicAuthClient = new IndirectBasicAuthClient(new SimpleTestUsernamePasswordAuthenticator()); TestsHelper.initShouldFail(basicAuthClient, "callbackUrl cannot be blank"); } private IndirectBasicAuthClient getBasicAuthClient() { final IndirectBasicAuthClient basicAuthClient = new IndirectBasicAuthClient(new SimpleTestUsernamePasswordAuthenticator()); basicAuthClient.setCallbackUrl(CALLBACK_URL); return basicAuthClient; } @Test public void testRedirectionUrl() throws HttpAction { final IndirectBasicAuthClient basicAuthClient = getBasicAuthClient(); MockWebContext context = MockWebContext.create(); basicAuthClient.redirect(context); assertEquals(CALLBACK_URL, context.getResponseLocation()); } @Test public void testGetCredentialsMissingHeader() { final IndirectBasicAuthClient basicAuthClient = getBasicAuthClient(); final MockWebContext context = MockWebContext.create(); verifyGetCredentialsFailsWithAuthenticationRequired(basicAuthClient, context); } @Test public void testGetCredentialsNotABasicHeader() { final IndirectBasicAuthClient basicAuthClient = getBasicAuthClient(); final MockWebContext context = getContextWithAuthorizationHeader("fakeHeader"); verifyGetCredentialsFailsWithAuthenticationRequired(basicAuthClient, context); } @Test public void testGetCredentialsBadFormatHeader() throws HttpAction { final IndirectBasicAuthClient basicAuthClient = getBasicAuthClient(); final MockWebContext context = getContextWithAuthorizationHeader("Basic fakeHeader"); verifyGetCredentialsFailsWithAuthenticationRequired(basicAuthClient, context); } @Test public void testGetCredentialsMissingSemiColon() throws HttpAction, UnsupportedEncodingException { final IndirectBasicAuthClient basicAuthClient = getBasicAuthClient(); final MockWebContext context = getContextWithAuthorizationHeader( "Basic " + Base64.getEncoder().encodeToString("fake".getBytes(HttpConstants.UTF8_ENCODING))); verifyGetCredentialsFailsWithAuthenticationRequired(basicAuthClient, context); } @Test public void testGetCredentialsBadCredentials() throws UnsupportedEncodingException { final IndirectBasicAuthClient basicAuthClient = getBasicAuthClient(); final String header = USERNAME + ":" + PASSWORD; final MockWebContext context = getContextWithAuthorizationHeader("Basic " + Base64.getEncoder().encodeToString(header.getBytes(HttpConstants.UTF8_ENCODING))); verifyGetCredentialsFailsWithAuthenticationRequired(basicAuthClient, context); } @Test public void testGetCredentialsGoodCredentials() throws HttpAction, UnsupportedEncodingException { final IndirectBasicAuthClient basicAuthClient = getBasicAuthClient(); final String header = USERNAME + ":" + USERNAME; final UsernamePasswordCredentials credentials = basicAuthClient.getCredentials( getContextWithAuthorizationHeader( "Basic " + Base64.getEncoder().encodeToString(header.getBytes(HttpConstants.UTF8_ENCODING)))); assertEquals(USERNAME, credentials.getUsername()); assertEquals(USERNAME, credentials.getPassword()); } private void verifyGetCredentialsFailsWithAuthenticationRequired( IndirectBasicAuthClient basicAuthClient, MockWebContext context) { try { basicAuthClient.getCredentials(context); fail("should throw HttpAction"); } catch (final HttpAction e) { assertEquals(401, context.getResponseStatus()); assertEquals("Basic realm=\"authentication required\"", context.getResponseHeaders().get(HttpConstants.AUTHENTICATE_HEADER)); assertEquals("Requires authentication", e.getMessage()); } } private MockWebContext getContextWithAuthorizationHeader(String value) { MockWebContext context = MockWebContext.create(); return context.addRequestHeader(HttpConstants.AUTHORIZATION_HEADER, value); } }