org.apigw.util.OAuthTestHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.apigw.util.OAuthTestHelper.java

Source

/**
 *   Copyright 2013 Stockholm County Council
 *
 *   This file is part of APIGW
 *
 *   APIGW is free software; you can redistribute it and/or modify
 *   it under the terms of version 2.1 of the GNU Lesser General Public
 *   License as published by the Free Software Foundation.
 *
 *   APIGW is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with APIGW; if not, write to the
 *   Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 *   Boston, MA 02111-1307  USA
 *
 */
package org.apigw.util;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Arrays;
import java.util.StringTokenizer;

import org.apigw.authserver.ServerRunning;
import org.apigw.authserver.TokenResponseDTO;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

/**
 * This class is based on code created by:
 * @author Dave Syer
 * @author Luke Taylor
 * The original code came from the Spring Security Oauth project: 
 *    https://github.com/SpringSource/spring-security-oauth
 * and is licensed under Apache License Version 2.0: 
 *    https://github.com/SpringSource/spring-security-oauth/blob/master/license.txt
 * 
 * The code has been modified and extended by:
 * @author Albert rwall
 * @author Christian Hilmersson 
 */
public class OAuthTestHelper {

    private ServerRunning serverRunning;
    private String username;
    private String password;

    public OAuthTestHelper(ServerRunning serverRunning, String username, String password) {
        super();
        this.serverRunning = serverRunning;
        this.username = username;
        this.password = password;
    }

    public String getAuthorizationCode(String clientId, String redirectUri, String scope) {
        String cookie = loginAndGetConfirmationPage(clientId, redirectUri, scope);
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
        headers.set("Cookie", cookie);
        MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
        formData.add("user_oauth_approval", "true");
        ResponseEntity<Void> result = serverRunning.postForStatus("/apigw-auth-server-web/oauth/authorize", headers,
                formData);
        assertEquals(HttpStatus.FOUND, result.getStatusCode());
        // Get the authorization code using the same session
        return getAuthorizationCode(result);
    }

    public String getAuthorizeUrl(String clientId, String redirectUri, String scope) {
        ServerRunning.UriBuilder uri = serverRunning.buildUri("/apigw-auth-server-web/oauth/authorize")
                .queryParam("response_type", "code").queryParam("state", "gzzFqB!!!").queryParam("scope", scope);
        if (clientId != null) {
            uri.queryParam("client_id", clientId);
        }
        if (redirectUri != null) {
            uri.queryParam("redirect_uri", redirectUri);
        }
        return uri.build().toString();
    }

    private String getAuthorizationCode(HttpEntity<Void> result) {

        String location = result.getHeaders().getLocation().toString();
        assertTrue(location.matches("http://.*code=.+"));

        String code = null;
        String state = null;
        for (StringTokenizer queryTokens = new StringTokenizer(result.getHeaders().getLocation().getQuery(),
                "&="); queryTokens.hasMoreTokens();) {
            String token = queryTokens.nextToken();
            if ("code".equals(token)) {
                if (code != null) {
                    fail("shouldn't have returned more than one code.");
                }

                code = queryTokens.nextToken();
            } else if ("state".equals(token)) {
                state = queryTokens.nextToken();
            }
        }

        assertEquals("gzzFqB!!!", state);
        assertNotNull(code);
        return code;

    }

    public String loginAndGetConfirmationPage(String clientId, String redirectUri, String scope) {

        String cookie = loginAndGrabCookie();

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
        headers.set("Cookie", cookie);

        ServerRunning.UriBuilder uri = serverRunning.buildUri("/apigw-auth-server-web/oauth/authorize")
                .queryParam("response_type", "code").queryParam("state", "gzzFqB!!!").queryParam("scope", scope);
        if (clientId != null) {
            uri.queryParam("client_id", clientId);
        }
        if (redirectUri != null) {
            uri.queryParam("redirect_uri", redirectUri);
        }

        ResponseEntity<String> response = serverRunning.getForString(uri.pattern(), headers, uri.params());

        // The confirm access page should be returned

        assertTrue(response.getBody().contains("API Test"));

        return cookie;

    }

    private String loginAndGrabCookie() {

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));

        MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
        formData.add("j_username", username);
        formData.add("j_password", password);

        // Should be redirected to the original URL, but now authenticated
        ResponseEntity<Void> result = serverRunning.postForStatus("/apigw-auth-server-web/login.do", headers,
                formData);

        assertEquals(HttpStatus.FOUND, result.getStatusCode());

        assertTrue(result.getHeaders().containsKey("Set-Cookie"));

        return result.getHeaders().getFirst("Set-Cookie");

    }

    public TokenResponseDTO getAccessToken(String clientId, String redirectUri, String cookie, String scope) {
        return getAccessToken(clientId, redirectUri, cookie, scope, HttpStatus.OK);
    }

    public TokenResponseDTO getAccessToken(String clientId, String redirectUri, String cookie, String scope,
            HttpStatus expectedStatus) {

        ResponseEntity<TokenResponseDTO> token = requestToken(clientId, redirectUri, cookie, scope);

        assertEquals(expectedStatus, token.getStatusCode());

        if (HttpStatus.OK == token.getStatusCode()) {
            return token.getBody();
        }

        return null;

    }

    public ResponseEntity<TokenResponseDTO> requestToken(String clientId, String redirectUri, String code,
            String scope) {
        MultiValueMap<String, String> formData = getTokenFormData(clientId, redirectUri, code, scope);

        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization",
                "Basic " + new String(Base64.encode(String.format("%s:secret", clientId).getBytes())));

        ResponseEntity<TokenResponseDTO> token = serverRunning.postForToken("/apigw-auth-server-intsvc/oauth/token",
                headers, formData);

        HttpHeaders responseHeaders = token.getHeaders();
        assertTrue("Missing no-store: " + responseHeaders,
                responseHeaders.get("Cache-Control").contains("no-store"));
        return token;
    }

    private MultiValueMap<String, String> getTokenFormData(String clientId, String redirectUri, String code,
            String scope) {
        MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
        formData.add("grant_type", "authorization_code");
        formData.add("client_id", clientId);
        formData.add("scope", scope);
        formData.add("redirect_uri", redirectUri);
        formData.add("state", "gzzFqB!!!");
        if (code != null) {
            formData.add("code", code);
        }
        return formData;
    }

    public ResponseEntity<Void> attemptToGetConfirmationPage(String clientId, String redirectUri, String scope) {

        String cookie = loginAndGrabCookie();

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
        headers.set("Cookie", cookie);

        return serverRunning.getForResponse(getAuthorizeUrl(clientId, redirectUri, scope), headers);

    }

}