package org.resthub.web.oauth2; import com.ning.http.client.AsyncHttpClientConfig.Builder; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.fest.assertions.api.Assertions; import org.resthub.web.Client; import org.resthub.web.Response; import org.resthub.web.exception.UnauthorizedClientException; import org.springframework.web.filter.DelegatingFilterProxy; import org.springframework.web.servlet.DispatcherServlet; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import javax.servlet.DispatcherType; import java.util.EnumSet; /** * Tests the the TokenFactory utility class. Launches an in-memory jetty server with two contexts: * <ol> * <li>an authorization service build upon resthub-oauth2-provider.</li> * <li>a resource service protected with resthub-oauth2-filter.</li> * </ol> */ // TODO: refactor those tests - use mocks and avoid Thread.sleep public class TestOAuth2Client { public static final String CLIENT_ID = "test"; public static final String CLIENT_SECRET = ""; public static final int PORT = 9796; public static final String BASE_URL = "http://localhost:" + PORT; public static final String ACCESS_TOKEN_ENDPOINT = BASE_URL + "/oauth/token"; /** * Jetty memory server instance. */ protected static Server server; protected static Builder builder; /** * Before the test suite, launches a Jetty in memory server. */ @BeforeTest public void beforeClass() throws Exception { // Creates a Jetty server. server = new Server(PORT); // Add a context for authorization service ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setDisplayName("resthub test webapp"); FilterHolder filterDef = new FilterHolder(DelegatingFilterProxy.class); filterDef.setName("springSecurityFilterChain"); filterDef.setInitParameter("contextAttribute", "org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring"); context.addFilter(filterDef, "/*", EnumSet.of(DispatcherType.REQUEST)); ServletHolder servletHolder = new ServletHolder(DispatcherServlet.class); servletHolder.setName("spring"); servletHolder.setInitOrder(1); servletHolder.setInitParameter("contextConfigLocation", "classpath*:resthubContext.xml classpath*:applicationContext.xml"); context.addServlet(servletHolder, "/"); // Starts the server. server.setHandler(context); server.start(); } /** * After the test suite, stops the Jetty in memory server. */ @AfterTest public void afterClass() throws Exception { if (server != null) { server.stop(); } } @Test public void testOAuth2SuccessfulRequest() { Client client = new Client().setOAuth2("test", "t3st", ACCESS_TOKEN_ENDPOINT, CLIENT_ID, CLIENT_SECRET); String result = client.url(BASE_URL + "/api/resource/hello").get().getBody(); Assertions.assertThat(result).isEqualTo("Hello"); } @Test(expectedExceptions = {UnauthorizedClientException.class}) public void testUnauthorizeRequest() { new Client().url(BASE_URL + "/api/resource/hello").jsonGet(); } @Test public void testTokenExpired() throws InterruptedException { Client client = new Client().setOAuth2("test", "t3st", ACCESS_TOKEN_ENDPOINT, CLIENT_ID, CLIENT_SECRET); String result = client.url(BASE_URL + "/api/resource/hello").get().getBody(); Assertions.assertThat(result).isEqualTo("Hello"); // wait for the token to expire Thread.sleep(1000L); // the client should detect its token is expired and ask for a new token result = client.url(BASE_URL + "/api/resource/hello").get().getBody(); Assertions.assertThat(result).isEqualTo("Hello"); } }