/* * Copyright 2012 SURFnet bv, The Netherlands * * 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 nl.surfnet.coin.selenium; import java.io.IOException; import java.net.URI; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import nl.surfnet.coin.api.client.internal.OpenConextApi20Implicit; import nl.surfnet.coin.mock.MockHandler; import nl.surfnet.coin.mock.MockHtppServer; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.scribe.builder.ServiceBuilder; import org.scribe.oauth.OAuthService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertNotNull; /** * Test Person related queries with selenium */ public class Oauth20ImplicitGrantTestSelenium extends SeleniumSupport { private static final String OAUTH_CALLBACK_URL = "http://localhost:8083/"; private Logger LOG = LoggerFactory.getLogger(Oauth20ImplicitGrantTestSelenium.class); private static final String OAUTH_KEY = "https://testsp.test.surfconext.nl/shibboleth"; private static final String OAUTH_SECRET = "mysecret"; private final static String OAUTH_OPENCONEXT_API_READ_SCOPE = "read"; private MockHtppServer server; private String callbackRequestFragment; @Before public void startServer() { LOG.debug("Starting server for catching authorization code..."); server = new MockHtppServer(8083) { protected MockHandler createHandler(Server server) { return new MockHandler(server) { @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (request.getRequestURI().contains("favicon")) { LOG.debug("ignoring favicon-request."); return; } LOG.debug("Request to mock http server: {}", request); response.setStatus(200); } }; } }; server.startServer(); } @Before public void clearCookies() { getRestartedWebDriver(); } @After public void stopServer() { LOG.debug("Stopping server..."); server.stopServer(); } @Before public void letMujinaReturnUrnCollabPerson() { letMujinaSendUrnCollabAttribute("some-user"); } @Test public void implicitGrant() throws Exception { final String restUrl = getApiBaseUrl() + "social/rest/people/foo/@self"; getWebDriver().get(restUrl); LOG.debug("Page source before authentication: " + getWebDriver().getPageSource()); assertFalse("Result of getPerson-call should fail because of missing authentication", getWebDriver().getPageSource().contains("Mister Foo")); OAuthService service = new ServiceBuilder().provider(OpenConextApi20Implicit.class).apiKey(OAUTH_KEY).apiSecret(OAUTH_SECRET) .callback(OAUTH_CALLBACK_URL).scope(OAUTH_OPENCONEXT_API_READ_SCOPE).build(); String authUrl = service.getAuthorizationUrl(null); LOG.debug("Auth url: {}", authUrl); getWebDriver().get(authUrl); loginAtMujinaIfNeeded(USER_ID); // Authorize on user consent page giveUserConsentIfNeeded(); URI uri = URI.create(getWebDriver().getCurrentUrl()); LOG.debug("URL is: " + uri.toString()); LOG.debug("Response body is: " + getWebDriver().getPageSource()); callbackRequestFragment = uri.getFragment(); assertNotNull("redirect URL should contain fragment.", callbackRequestFragment); assertTrue("redirect URL fragment should contain access token", callbackRequestFragment.contains("access_token=")); assertFalse("redirect URL fragment should NOT contain an expires_in parameter", callbackRequestFragment.contains("expires_in=")); // Further tests are actually part of the coin-api-client... The server has // issued an access_token so it works. } @Test public void implicitGrantWithDeny() throws Exception { OAuthService service = new ServiceBuilder().provider(OpenConextApi20Implicit.class) .apiKey(OAUTH_KEY.concat(UUID.randomUUID().toString())).apiSecret(OAUTH_SECRET.concat("force_consent")) .callback(OAUTH_CALLBACK_URL).scope(OAUTH_OPENCONEXT_API_READ_SCOPE).build(); String authUrl = service.getAuthorizationUrl(null); LOG.debug("Auth url: {}", authUrl); getWebDriver().get(authUrl); loginAtMujinaIfNeeded(USER_ID); // Deny on user consent page WebElement authorizeButton = getWebDriver().findElement(By.id("decline_terms_button")); authorizeButton.click(); URI uri = URI.create(getWebDriver().getCurrentUrl()); LOG.debug("URL is: " + uri.toString()); LOG.debug("Response body is: " + getWebDriver().getPageSource()); callbackRequestFragment = uri.getFragment(); assertNotNull("redirect URL should contain fragment.", callbackRequestFragment); assertFalse("redirect URL fragment should not contain access token", callbackRequestFragment.contains("access_token=")); assertFalse("redirect URL fragment should contain access token", callbackRequestFragment.contains("access_token=")); } @Test public void noRedirectUriGiven() { String url = getApiBaseUrl() + "oauth2/authorize?client_id=someclient&response_type=token"; getWebDriver().get(url); loginAtMujinaIfNeeded(USER_ID); // Authorize on user consent page giveUserConsentIfNeeded(); String pageSource = getWebDriver().getPageSource(); LOG.debug("Response body is: " + pageSource); assertTrue("Page should contain correct error message", pageSource.contains("does not match one of the registered values")); assertFalse("Page should not be a 500", pageSource.contains("500")); // callbackRequestFragment = uri.getFragment(); } }