<commit_before>/*
  Copyright 2015 - 2015 pac4j organization

   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.pac4j.vertx;

import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpClientRequest;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
import org.pac4j.core.client.Client;
import org.pac4j.core.client.Clients;
import org.pac4j.core.config.Config;
import org.pac4j.core.matching.ExcludedPathMatcher;
import org.pac4j.http.client.direct.DirectBasicAuthClient;
import org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator;
import org.pac4j.vertx.auth.Pac4jAuthProvider;
import org.pac4j.vertx.handler.impl.Pac4jAuthHandlerOptions;
import org.pac4j.vertx.handler.impl.RequiresAuthenticationHandler;

import java.util.ArrayList;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import static org.hamcrest.CoreMatchers.is;

/**
 * @author <NAME>
 * @since 2.0.0
 */
public class StatelessPac4jAuthHandlerIntegrationTest extends Pac4jAuthHandlerIntegrationTestBase {

    private static final String AUTH_HEADER_NAME = "Authorization";
    private static final String BASIC_AUTH_PREFIX = "Basic ";
    public static final String TEST_USER_NAME = "testUser";
    private static final String TEST_BASIC_AUTH_HEADER = BASIC_AUTH_PREFIX + Base64.encodeBase64String((TEST_USER_NAME + ":testUser").getBytes());
    private static final String TEST_FAILING_BASIC_AUTH_HEADER = BASIC_AUTH_PREFIX + Base64.encodeBase64String((TEST_USER_NAME + ":testUser2").getBytes());
    public static final String PROTECTED_RESOURCE_URL = "/private/success.html";
    public static final String BASIC_AUTH_CLIENT = "BasicAuthClient";
    private static final String USERNAME_FIELD = "username";
    public static final String EXCLUDED_PATH_MATCHER_NAME = "ExcludedPathMatcher";

    @Test
    public void testSuccessfulLogin() throws Exception {

        testProtectedResourceAccessWithCredentials(TEST_BASIC_AUTH_HEADER, 200, protectedResourceContentValidator());

    }

    @Test
    public void testFailedLogin() throws Exception {

        testProtectedResourceAccessWithCredentials(TEST_FAILING_BASIC_AUTH_HEADER, 401, unauthorizedContentValidator());

    }

    @Test
    public void testExcludedUrlIsAccessibleWithoutCredentials() throws Exception {
        testResourceAccessWithoutCredentials(EXCLUDED_PROTECTED_RESOURCE_URL, 200, unprotectedResourceContentValidator());
    }

    @Test
    public void testExcludedUrlIsAccessibleWithInvalidCredentials() throws Exception {
        testResourceAccess(EXCLUDED_PROTECTED_RESOURCE_URL, Optional.of(TEST_FAILING_BASIC_AUTH_HEADER), 200, unprotectedResourceContentValidator());
    }

    @Override
    protected void validateProtectedResourceContent(JsonObject jsonObject) {
        assertThat(jsonObject.getString(USERNAME_FIELD), is(TEST_USER_NAME));
    }

    protected Consumer<String> unprotectedResourceContentValidator() {
        return s -> s.equals(UNPROTECTED_RESOURCE_BODY);
    }

    private void testResourceAccessWithoutCredentials(final String url,
                                                      final int expectedHttpStatus,
                                                      final Consumer<String> bodyValidator) throws Exception {
        testResourceAccess(url, Optional.empty(), expectedHttpStatus, bodyValidator);
    }

    private void testProtectedResourceAccessWithCredentials(final String credentialsHeader, final int expectedHttpStatus, final Consumer<String> bodyValidator) throws Exception {
        testResourceAccess(PROTECTED_RESOURCE_URL, Optional.of(credentialsHeader), expectedHttpStatus, bodyValidator);
    }

    private void testResourceAccess(final String url,
                                    final Optional<String> credentialsHeader,
                                    final int expectedHttpStatus,
                                    final Consumer<String> bodyValidator) throws Exception {
        startWebServer();
        HttpClient client = vertx.createHttpClient();
        // Attempt to get a private url
        final HttpClientRequest request = client.get(8080, "localhost", url);
        credentialsHeader.ifPresent(header -> request.putHeader(AUTH_HEADER_NAME, header));
        // This should get the desired result straight away rather than operating through redirects
        request.handler(response -> {
            assertEquals(expectedHttpStatus, response.statusCode());
            response.bodyHandler(body -> {
                final String bodyContent = body.toString();
                bodyValidator.accept(bodyContent);
                testComplete();
            });
        });
        request.end();
        await(1, TimeUnit.SECONDS);

    }

    private Consumer<String> unauthorizedContentValidator() {<commit_msg>Extend test timeout as we just blew it on the last commit.<commit_after>/*
  Copyright 2015 - 2015 pac4j organization

   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.pac4j.vertx;

import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpClientRequest;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
import org.pac4j.core.client.Client;
import org.pac4j.core.client.Clients;
import org.pac4j.core.config.Config;
import org.pac4j.core.matching.ExcludedPathMatcher;
import org.pac4j.http.client.direct.DirectBasicAuthClient;
import org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator;
import org.pac4j.vertx.auth.Pac4jAuthProvider;
import org.pac4j.vertx.handler.impl.Pac4jAuthHandlerOptions;
import org.pac4j.vertx.handler.impl.RequiresAuthenticationHandler;

import java.util.ArrayList;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import static org.hamcrest.CoreMatchers.is;

/**
 * @author <NAME>
 * @since 2.0.0
 */
public class StatelessPac4jAuthHandlerIntegrationTest extends Pac4jAuthHandlerIntegrationTestBase {

    private static final String AUTH_HEADER_NAME = "Authorization";
    private static final String BASIC_AUTH_PREFIX = "Basic ";
    public static final String TEST_USER_NAME = "testUser";
    private static final String TEST_BASIC_AUTH_HEADER = BASIC_AUTH_PREFIX + Base64.encodeBase64String((TEST_USER_NAME + ":testUser").getBytes());
    private static final String TEST_FAILING_BASIC_AUTH_HEADER = BASIC_AUTH_PREFIX + Base64.encodeBase64String((TEST_USER_NAME + ":testUser2").getBytes());
    public static final String PROTECTED_RESOURCE_URL = "/private/success.html";
    public static final String BASIC_AUTH_CLIENT = "BasicAuthClient";
    private static final String USERNAME_FIELD = "username";
    public static final String EXCLUDED_PATH_MATCHER_NAME = "ExcludedPathMatcher";

    @Test
    public void testSuccessfulLogin() throws Exception {

        testProtectedResourceAccessWithCredentials(TEST_BASIC_AUTH_HEADER, 200, protectedResourceContentValidator());

    }

    @Test
    public void testFailedLogin() throws Exception {

        testProtectedResourceAccessWithCredentials(TEST_FAILING_BASIC_AUTH_HEADER, 401, unauthorizedContentValidator());

    }

    @Test
    public void testExcludedUrlIsAccessibleWithoutCredentials() throws Exception {
        testResourceAccessWithoutCredentials(EXCLUDED_PROTECTED_RESOURCE_URL, 200, unprotectedResourceContentValidator());
    }

    @Test
    public void testExcludedUrlIsAccessibleWithInvalidCredentials() throws Exception {
        testResourceAccess(EXCLUDED_PROTECTED_RESOURCE_URL, Optional.of(TEST_FAILING_BASIC_AUTH_HEADER), 200, unprotectedResourceContentValidator());
    }

    @Override
    protected void validateProtectedResourceContent(JsonObject jsonObject) {
        assertThat(jsonObject.getString(USERNAME_FIELD), is(TEST_USER_NAME));
    }

    protected Consumer<String> unprotectedResourceContentValidator() {
        return s -> s.equals(UNPROTECTED_RESOURCE_BODY);
    }

    private void testResourceAccessWithoutCredentials(final String url,
                                                      final int expectedHttpStatus,
                                                      final Consumer<String> bodyValidator) throws Exception {
        testResourceAccess(url, Optional.empty(), expectedHttpStatus, bodyValidator);
    }

    private void testProtectedResourceAccessWithCredentials(final String credentialsHeader, final int expectedHttpStatus, final Consumer<String> bodyValidator) throws Exception {
        testResourceAccess(PROTECTED_RESOURCE_URL, Optional.of(credentialsHeader), expectedHttpStatus, bodyValidator);
    }

    private void testResourceAccess(final String url,
                                    final Optional<String> credentialsHeader,
                                    final int expectedHttpStatus,
                                    final Consumer<String> bodyValidator) throws Exception {
        startWebServer();
        HttpClient client = vertx.createHttpClient();
        // Attempt to get a private url
        final HttpClientRequest request = client.get(8080, "localhost", url);
        credentialsHeader.ifPresent(header -> request.putHeader(AUTH_HEADER_NAME, header));
        // This should get the desired result straight away rather than operating through redirects
        request.handler(response -> {
            assertEquals(expectedHttpStatus, response.statusCode());
            response.bodyHandler(body -> {
                final String bodyContent = body.toString();
                bodyValidator.accept(bodyContent);
                testComplete();
            });
        });
        request.end();
        await(2, TimeUnit.SECONDS);

    }

    private Consumer<String> unauthorizedContentValidator() {
{'fraction_non_alphanumeric': 0.07503884471254912, 'fraction_numerical': 0.010602321542820583, 'mean_word_length': 3.694122694122694, 'pattern_counts': {'":': 4, '<': 17, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1221680', 'n_tokens_mistral': 2919, 'n_tokens_neox': 2770, 'n_words': 695}