io.apiman.gateway.engine.policies.BasicAuthJDBCTest.java Source code

Java tutorial

Introduction

Here is the source code for io.apiman.gateway.engine.policies.BasicAuthJDBCTest.java

Source

/*
 * Copyright 2014 JBoss Inc
 *
 * 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 io.apiman.gateway.engine.policies;

import io.apiman.gateway.engine.beans.ApiRequest;
import io.apiman.gateway.engine.beans.PolicyFailure;
import io.apiman.gateway.engine.beans.PolicyFailureType;
import io.apiman.gateway.engine.components.IJdbcComponent;
import io.apiman.gateway.engine.components.IPolicyFailureFactoryComponent;
import io.apiman.gateway.engine.impl.DefaultJdbcComponent;
import io.apiman.gateway.engine.policies.config.BasicAuthenticationConfig;
import io.apiman.gateway.engine.policy.IPolicyChain;
import io.apiman.gateway.engine.policy.IPolicyContext;
import io.apiman.test.common.util.TestUtil;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;

import javax.naming.InitialContext;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.dbcp.BasicDataSource;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;

/**
 * Unit test.
 *
 * @author eric.wittmann@redhat.com
 */
@SuppressWarnings({ "nls", "javadoc" })
public class BasicAuthJDBCTest {

    private static final String JDBC_USER = "bwayne";
    private static final String JDBC_PASSWORD = "bwayne123!";

    @BeforeClass
    public static void setup() throws Exception {
        // Create a test datasource and bind it to JNDI
        BasicDataSource ds = createInMemoryDatasource();
        InitialContext ctx = TestUtil.initialContext();
        TestUtil.ensureCtx(ctx, "java:comp/env"); //$NON-NLS-1$
        TestUtil.ensureCtx(ctx, "java:comp/env/jdbc"); //$NON-NLS-1$
        ctx.bind("java:comp/env/jdbc/BasicAuthJDBCTest", ds); //$NON-NLS-1$
    }

    /**
     * Test method for {@link io.apiman.gateway.engine.policies.BasicAuthenticationPolicy#apply(ApiRequest, IPolicyContext, Object, IPolicyChain)}.
     */
    @Test
    public void testApplyJdbcNoRoles_DS() throws Exception {
        String json = "{\r\n" + "    \"realm\" : \"TestRealm\",\r\n"
                + "    \"forwardIdentityHttpHeader\" : \"X-Authenticated-Identity\",\r\n"
                + "    \"jdbcIdentity\" : {\r\n" + "        \"datasourcePath\" : \"jdbc/BasicAuthJDBCTest\",\r\n"
                + "        \"query\" : \"SELECT * FROM users WHERE username = ? AND password = ?\",\r\n"
                + "        \"hashAlgorithm\" : \"SHA1\"\r\n" + "    }\r\n" + "}";
        testApplyJdbcNoRoles(json);
    }

    /**
     * Test method for {@link io.apiman.gateway.engine.policies.BasicAuthenticationPolicy#apply(ApiRequest, IPolicyContext, Object, IPolicyChain)}.
     */
    @Test
    public void testApplyJdbcWithRoles_DS() throws Exception {
        String json = "{\r\n" + "    \"realm\" : \"TestRealm\",\r\n"
                + "    \"forwardIdentityHttpHeader\" : \"X-Authenticated-Identity\",\r\n"
                + "    \"jdbcIdentity\" : {\r\n" + "        \"datasourcePath\" : \"jdbc/BasicAuthJDBCTest\",\r\n"
                + "        \"query\" : \"SELECT * FROM users WHERE username = ? AND password = ?\",\r\n"
                + "        \"hashAlgorithm\" : \"SHA1\",\r\n" + "        \"extractRoles\" : true,\r\n"
                + "        \"roleQuery\" : \"SELECT r.rolename FROM roles r WHERE r.username = ?\"\r\n"
                + "    }\r\n" + "}";
        testApplyJdbcWithRoles(json);
    }

    /**
     * Test method for {@link io.apiman.gateway.engine.policies.BasicAuthenticationPolicy#apply(ApiRequest, IPolicyContext, Object, IPolicyChain)}.
     */
    @Test
    public void testApplyJdbcNoRoles_URL() throws Exception {
        String json = "{\r\n" + "    \"realm\" : \"TestRealm\",\r\n"
                + "    \"forwardIdentityHttpHeader\" : \"X-Authenticated-Identity\",\r\n"
                + "    \"jdbcIdentity\" : {\r\n" + "        \"type\" : \"url\",\r\n"
                + "        \"jdbcUrl\" : \"jdbc:h2:mem:BasicAuthJDBCTest;DB_CLOSE_DELAY=-1\",\r\n"
                + "        \"username\" : \"sa\",\r\n" + "        \"password\" : \"\",\r\n"
                + "        \"query\" : \"SELECT * FROM users WHERE username = ? AND password = ?\",\r\n"
                + "        \"hashAlgorithm\" : \"SHA1\"\r\n" + "    }\r\n" + "}";
        testApplyJdbcNoRoles(json);
    }

    /**
     * Test method for {@link io.apiman.gateway.engine.policies.BasicAuthenticationPolicy#apply(ApiRequest, IPolicyContext, Object, IPolicyChain)}.
     */
    @Test
    public void testApplyJdbcWithRoles_URL() throws Exception {
        String json = "{\r\n" + "    \"realm\" : \"TestRealm\",\r\n"
                + "    \"forwardIdentityHttpHeader\" : \"X-Authenticated-Identity\",\r\n"
                + "    \"jdbcIdentity\" : {\r\n" + "        \"type\" : \"url\",\r\n"
                + "        \"jdbcUrl\" : \"jdbc:h2:mem:BasicAuthJDBCTest;DB_CLOSE_DELAY=-1\",\r\n"
                + "        \"username\" : \"sa\",\r\n" + "        \"password\" : \"\",\r\n"
                + "        \"query\" : \"SELECT * FROM users WHERE username = ? AND password = ?\",\r\n"
                + "        \"hashAlgorithm\" : \"SHA1\",\r\n" + "        \"extractRoles\" : true,\r\n"
                + "        \"roleQuery\" : \"SELECT r.rolename FROM roles r WHERE r.username = ?\"\r\n"
                + "    }\r\n" + "}";
        testApplyJdbcWithRoles(json);
    }

    /**
     * @param json
     * @throws Exception
     */
    public void testApplyJdbcNoRoles(String json) throws Exception {
        // A live LDAP server is required to run this test!
        BasicAuthenticationPolicy policy = new BasicAuthenticationPolicy();
        BasicAuthenticationConfig config = policy.parseConfiguration(json);
        ApiRequest request = new ApiRequest();
        request.setType("GET");
        request.setApiKey("12345");
        request.setRemoteAddr("1.2.3.4");
        request.setDestination("/");
        IPolicyContext context = Mockito.mock(IPolicyContext.class);
        final PolicyFailure failure = new PolicyFailure();
        Mockito.when(context.getComponent(IPolicyFailureFactoryComponent.class))
                .thenReturn(new IPolicyFailureFactoryComponent() {
                    @Override
                    public PolicyFailure createFailure(PolicyFailureType type, int failureCode, String message) {
                        return failure;
                    }
                });
        Mockito.when(context.getComponent(IJdbcComponent.class)).thenReturn(new DefaultJdbcComponent());
        IPolicyChain<ApiRequest> chain = Mockito.mock(IPolicyChain.class);

        // Failure
        policy.apply(request, context, config, chain);
        Mockito.verify(chain).doFailure(failure);

        // Failure
        request.getHeaders().put("Authorization", createBasicAuthorization(JDBC_USER, "invalid_password"));
        chain = Mockito.mock(IPolicyChain.class);
        policy.apply(request, context, config, chain);
        Mockito.verify(chain).doFailure(failure);

        // Success
        request.getHeaders().put("Authorization", createBasicAuthorization(JDBC_USER, JDBC_PASSWORD));
        chain = Mockito.mock(IPolicyChain.class);
        policy.apply(request, context, config, chain);
        Mockito.verify(chain).doApply(request);
    }

    public void testApplyJdbcWithRoles(String json) throws Exception {
        // A live LDAP server is required to run this test!
        BasicAuthenticationPolicy policy = new BasicAuthenticationPolicy();
        BasicAuthenticationConfig config = policy.parseConfiguration(json);
        ApiRequest request = new ApiRequest();
        request.setType("GET");
        request.setApiKey("12345");
        request.setRemoteAddr("1.2.3.4");
        request.setDestination("/");
        IPolicyContext context = Mockito.mock(IPolicyContext.class);
        Mockito.when(context.getComponent(IJdbcComponent.class)).thenReturn(new DefaultJdbcComponent());
        IPolicyChain<ApiRequest> chain = Mockito.mock(IPolicyChain.class);

        // Success
        request.getHeaders().put("Authorization", createBasicAuthorization(JDBC_USER, JDBC_PASSWORD));
        chain = Mockito.mock(IPolicyChain.class);
        policy.apply(request, context, config, chain);
        Mockito.verify(chain).doApply(request);
        Set<String> expectedRoles = new HashSet<>();
        expectedRoles.add("admin");
        expectedRoles.add("user");
        Mockito.verify(context).setAttribute(AuthorizationPolicy.AUTHENTICATED_USER_ROLES, expectedRoles);
    }

    /**
     * Creates the http Authorization string for the given credentials.
     * @param username
     * @param password
     */
    private String createBasicAuthorization(String username, String password) {
        String creds = username + ":" + password;
        StringBuilder builder = new StringBuilder();
        builder.append("Basic ");
        builder.append(Base64.encodeBase64String(creds.getBytes()));
        return builder.toString();
    }

    /**
     * Creates an in-memory datasource.
     * @throws SQLException
     */
    private static BasicDataSource createInMemoryDatasource() throws SQLException {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName(Driver.class.getName());
        ds.setUsername("sa"); //$NON-NLS-1$
        ds.setPassword(""); //$NON-NLS-1$
        ds.setUrl("jdbc:h2:mem:BasicAuthJDBCTest;DB_CLOSE_DELAY=-1"); //$NON-NLS-1$
        Connection connection = ds.getConnection();
        connection.prepareStatement(
                "CREATE TABLE users ( username varchar(255) NOT NULL, password varchar(255) NOT NULL, PRIMARY KEY (username))")
                .executeUpdate();
        connection.prepareStatement(
                "INSERT INTO users (username, password) VALUES ('bwayne', 'ae2efd698aefdf366736a4eda1bc5241f9fbfec7')")
                .executeUpdate();
        connection.prepareStatement(
                "INSERT INTO users (username, password) VALUES ('ckent', 'ea59f7ca52a2087c99374caba0ff29be1b2dcdbf')")
                .executeUpdate();
        connection.prepareStatement(
                "INSERT INTO users (username, password) VALUES ('ballen', 'ea59f7ca52a2087c99374caba0ff29be1b2dcdbf')")
                .executeUpdate();
        connection
                .prepareStatement(
                        "CREATE TABLE roles (rolename varchar(255) NOT NULL, username varchar(255) NOT NULL)")
                .executeUpdate();
        connection.prepareStatement("INSERT INTO roles (rolename, username) VALUES ('user', 'bwayne')")
                .executeUpdate();
        connection.prepareStatement("INSERT INTO roles (rolename, username) VALUES ('admin', 'bwayne')")
                .executeUpdate();
        connection.prepareStatement("INSERT INTO roles (rolename, username) VALUES ('ckent', 'user')")
                .executeUpdate();
        connection.prepareStatement("INSERT INTO roles (rolename, username) VALUES ('ballen', 'user')")
                .executeUpdate();
        connection.close();
        return ds;
    }
}