org.openanzo.test.TestEncryptedTokenAuthorizationBlocksServletAccess.java Source code

Java tutorial

Introduction

Here is the source code for org.openanzo.test.TestEncryptedTokenAuthorizationBlocksServletAccess.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Cambridge Semantics Incorporated.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Cambridge Semantics Incorporated
 *******************************************************************************/
package org.openanzo.test;

import java.util.Properties;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.openanzo.rdf.utils.Pair;
import org.openanzo.services.EncryptedTokenAuthenticatorConstants;
import org.openanzo.services.ServicesProperties;
import org.openanzo.servlet.control.ControlServlet;

/**
 * Tests for the EncryptedTokenAuthorization class which test whether the class properly protects servlets.
 * 
 * This class was built to test the situation found in ticket http://www.openanzo.org/projects/openanzo/ticket/852 in which a request to authenticate was
 * handled by both the authenticator and the servlet when it should have only been handled by the authenticator.
 * 
 * Many of these tests depend on the 'ControlServlet' being setup and responding to commands to increment and read a counter that the servlet keeps internally.
 * 
 * @author Jordi Albornoz Mulligan ( <a href="mailto:jordi@cambridgesemantics.com">jordi@cambridgesemantics.com </a>)
 */
public class TestEncryptedTokenAuthorizationBlocksServletAccess extends AbstractTest {

    private static final String PROTECTED_URI_PATH = "protected/";

    private String getControlServletURI() {
        String port = getProperties().getProperty("http.port");
        String uri = "http://localhost:" + port + "/control/";
        return uri;
    }

    private Pair<String, String> getDefaultUserAndPassword() throws Exception {
        Properties properties = getProperties();
        String user = ServicesProperties.getUser(properties, "default");
        String password = ServicesProperties.getPassword(properties, "123");
        Pair<String, String> info = new Pair<String, String>(user, password);
        return info;
    }

    private void resetServletCounter() throws Exception {
        HttpClient client = new HttpClient();
        String uri = getControlServletURI() + ControlServlet.OPERATION_URI_SUFFIX_COUNTER_RESET;
        GetMethod request = new GetMethod(uri);
        request.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        client.executeMethod(request);
        int statusCode = request.getStatusCode();
        assertEquals("Invalid status code. Status text: " + request.getStatusText(), HttpStatus.SC_OK, statusCode);
        assertEquals("0", request.getResponseBodyAsString());
    }

    /**
     * Make sure that the ControlServlet's incrementing counter functionality works properly since most of the other tests depend on it.
     * 
     * @throws Exception
     */
    public void testControlServletIncrementsCounter() throws Exception {
        resetServletCounter();

        // Try to tell the servlet to increment the counter (via an unprotected path)
        HttpClient client = new HttpClient();
        GetMethod request = new GetMethod(getControlServletURI() + "increment_the_counter");
        request.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        client.executeMethod(request);
        int statusCode = request.getStatusCode();
        assertEquals("Invalid status code. Status text: " + request.getStatusText(), HttpStatus.SC_OK, statusCode);
        assertEquals("1", request.getResponseBodyAsString());

        // Increment again
        client = new HttpClient();
        request = new GetMethod(getControlServletURI() + "increment_it_again");
        request.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        client.executeMethod(request);
        statusCode = request.getStatusCode();
        assertEquals("Invalid status code. Status text: " + request.getStatusText(), HttpStatus.SC_OK, statusCode);
        assertEquals("2", request.getResponseBodyAsString());
    }

    /**
     * Trying to access a protected path without proper authentication should prevent access to the servlet.
     * 
     * @throws Exception
     */
    public void testUnauthenticatedProtectedPathAccessDoesNotReachServlet() throws Exception {
        resetServletCounter();

        // Try to tell the servlet to increment the counter via a path that is protected by authentication.
        // This should fail via an authentication error.
        HttpClient client = new HttpClient();
        GetMethod request = new GetMethod(getControlServletURI() + PROTECTED_URI_PATH + "increment_the_counter");
        request.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        client.executeMethod(request);
        int statusCode = request.getStatusCode();
        assertEquals("Invalid status code. Status text: " + request.getStatusText(), HttpStatus.SC_FORBIDDEN,
                statusCode);

        // Get the value of the counter (via a non-protected path) to make sure it stayed at zero.
        request = new GetMethod(getControlServletURI() + ControlServlet.OPERATION_URI_SUFFIX_COUNTER_READ);
        request.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        client.executeMethod(request);
        statusCode = request.getStatusCode();
        assertEquals("Invalid status code. Status text: " + request.getStatusText(), HttpStatus.SC_OK, statusCode);
        assertEquals("0", request.getResponseBodyAsString());
    }

    /**
     * An authenticate request should not invoke the protected servlet. It should be handled only by the authenticator in both successful and invalid
     * authentication cases.
     * 
     * @throws Exception
     */
    public void testSuccessfulAuthenticateRequestDoesNotReachServlet() throws Exception {
        resetServletCounter();

        Pair<String, String> userInfo = getDefaultUserAndPassword();

        // Send a authentication request that we expect to succeed.
        HttpClient client = new HttpClient();
        PostMethod authpost = new PostMethod(
                getControlServletURI() + EncryptedTokenAuthenticatorConstants.LOGIN_URI_SUFFIX);
        NameValuePair formUserid = new NameValuePair(EncryptedTokenAuthenticatorConstants.USERNAME_PARAMETER_NAME,
                userInfo.first);
        NameValuePair formPassword = new NameValuePair(EncryptedTokenAuthenticatorConstants.PASSWORD_PARAMETER_NAME,
                userInfo.second);
        authpost.setRequestBody(new NameValuePair[] { formUserid, formPassword });
        authpost.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        authpost.setDoAuthentication(false);
        client.executeMethod(authpost);
        int statusCode = authpost.getStatusCode();
        assertEquals("Invalid status code. Status text: " + authpost.getStatusText(), HttpStatus.SC_OK, statusCode);
        authpost.releaseConnection();
        Cookie[] logoncookies = client.getState().getCookies();
        boolean authenticated = false;
        for (int i = 0; i < logoncookies.length; i++) {
            if (logoncookies[i].getName().equals(EncryptedTokenAuthenticatorConstants.ANZO_TOKEN_COOKIE_NAME))
                authenticated = true;
        }
        assertTrue("Expect a successful authentication.", authenticated);

        // Get the value of the counter (via a non-protected path) to make sure it stayed at zero, which would indicate the
        // servlet wasn't touched by the authenticate request.
        GetMethod request = new GetMethod(
                getControlServletURI() + ControlServlet.OPERATION_URI_SUFFIX_COUNTER_READ);
        request.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        client.executeMethod(request);
        statusCode = request.getStatusCode();
        assertEquals("Invalid status code. Status text: " + request.getStatusText(), HttpStatus.SC_OK, statusCode);
        assertEquals("0", request.getResponseBodyAsString());
    }

    /**
     * An authenticate request should not invoke the protected servlet. It should be handled only by the authenticator in both successful and invalid
     * authentication cases.
     * 
     * @throws Exception
     */
    public void testFailedAuthenticateRequestDoesNotReachServlet() throws Exception {
        resetServletCounter();

        Pair<String, String> userInfo = getDefaultUserAndPassword();

        // Send a authentication request that we expect to fail.
        HttpClient client = new HttpClient();
        PostMethod authpost = new PostMethod(
                getControlServletURI() + EncryptedTokenAuthenticatorConstants.LOGIN_URI_SUFFIX);
        NameValuePair formUserid = new NameValuePair(EncryptedTokenAuthenticatorConstants.USERNAME_PARAMETER_NAME,
                userInfo.first);
        NameValuePair formPassword = new NameValuePair(EncryptedTokenAuthenticatorConstants.PASSWORD_PARAMETER_NAME,
                "anIncorrectPassword");
        authpost.setRequestBody(new NameValuePair[] { formUserid, formPassword });
        authpost.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        authpost.setDoAuthentication(false);
        client.executeMethod(authpost);
        int statusCode = authpost.getStatusCode();
        assertEquals("Invalid status code. Status text: " + authpost.getStatusText(), HttpStatus.SC_FORBIDDEN,
                statusCode);
        authpost.releaseConnection();
        Cookie[] logoncookies = client.getState().getCookies();
        boolean authenticated = false;
        for (int i = 0; i < logoncookies.length; i++) {
            if (logoncookies[i].getName().equals(EncryptedTokenAuthenticatorConstants.ANZO_TOKEN_COOKIE_NAME))
                authenticated = true;
        }
        assertFalse("Expect a failed authentication.", authenticated);

        // Get the value of the counter (via a non-protected path) to make sure it stayed at zero, which would indicate the
        // servlet wasn't touched by the authenticate request.
        GetMethod request = new GetMethod(
                getControlServletURI() + ControlServlet.OPERATION_URI_SUFFIX_COUNTER_READ);
        request.addRequestHeader("X-Requested-With", "XMLHttpRequest");
        client.executeMethod(request);
        statusCode = request.getStatusCode();
        assertEquals("Invalid status code. Status text: " + request.getStatusText(), HttpStatus.SC_OK, statusCode);
        assertEquals("0", request.getResponseBodyAsString());
    }

}