/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.shindig.gadgets.oauth;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.apache.shindig.auth.BasicSecurityToken;
import org.apache.shindig.auth.SecurityToken;
import org.apache.shindig.common.cache.LruCacheProvider;
import org.apache.shindig.common.crypto.BasicBlobCrypter;
import org.apache.shindig.common.util.CharsetUtil;
import org.apache.shindig.common.util.FakeTimeSource;
import org.apache.shindig.gadgets.FakeGadgetSpecFactory;
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.RequestSigningException;
import org.apache.shindig.gadgets.http.DefaultHttpCache;
import org.apache.shindig.gadgets.http.HttpResponse;
import org.apache.shindig.gadgets.oauth.AccessorInfo.OAuthParamLocation;
import org.apache.shindig.gadgets.oauth.BasicOAuthStoreConsumerKeyAndSecret.KeyType;
import org.apache.shindig.gadgets.oauth.OAuthArguments.UseToken;
import org.apache.shindig.gadgets.oauth.testing.FakeOAuthServiceProvider;
import org.apache.shindig.gadgets.oauth.testing.MakeRequestClient;
import org.apache.shindig.gadgets.oauth.testing.FakeOAuthServiceProvider.TokenPair;
import com.google.common.collect.Lists;
import net.oauth.OAuth;
import net.oauth.OAuth.Parameter;
import org.apache.commons.codec.binary.Base64;
import org.json.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
/**
* Tests for signing requests.
*/
public class OAuthFetcherTest {
private OAuthFetcherConfig fetcherConfig;
private FakeOAuthServiceProvider serviceProvider;
private BasicOAuthStore base;
private Logger logger;
private final List<LogRecord> logRecords = Lists.newArrayList();
private FakeTimeSource clock = new FakeTimeSource();
public static final String GADGET_URL = "http://www.example.com/gadget.xml";
public static final String GADGET_URL_NO_KEY = "http://www.example.com/nokey.xml";
public static final String GADGET_URL_HEADER = "http://www.example.com/header.xml";
public static final String GADGET_URL_BODY = "http://www.example.com/body.xml";
@Before
public void setUp() throws Exception {
base = new BasicOAuthStore();
serviceProvider = new FakeOAuthServiceProvider(clock);
fetcherConfig = new OAuthFetcherConfig(
new BasicBlobCrypter("abcdefghijklmnop".getBytes()),
getOAuthStore(base),
new DefaultHttpCache(new LruCacheProvider(10)),
clock);
logger = Logger.getLogger(OAuthFetcher.class.getName());
logger.addHandler(new Handler() {
@Override
public void close() throws SecurityException {
}
@Override
public void flush() {
}
@Override
public void publish(LogRecord arg0) {
logRecords.add(arg0);
}
});
}
/**
* Builds a nicely populated fake token store.
*/
public static GadgetOAuthTokenStore getOAuthStore(BasicOAuthStore base) throws GadgetException {
if (base == null) {
base = new BasicOAuthStore();
}
addValidConsumer(base);
addInvalidConsumer(base);
addAuthHeaderConsumer(base);
addBodyConsumer(base);
addDefaultKey(base);
GadgetOAuthTokenStore store = new GadgetOAuthTokenStore(base, new FakeGadgetSpecFactory());
base.initFromConfigString("{}");
return store;
}
private static void addValidConsumer(BasicOAuthStore base) {
addConsumer(
base,
GADGET_URL,
FakeGadgetSpecFactory.SERVICE_NAME,
FakeOAuthServiceProvider.CONSUMER_KEY,
FakeOAuthServiceProvider.CONSUMER_SECRET);
}
private static void addInvalidConsumer(BasicOAuthStore base) {
addConsumer(
base,
GADGET_URL_NO_KEY,
FakeGadgetSpecFactory.SERVICE_NAME_NO_KEY,
"garbage_key", "garbage_secret");
}
private static void addAuthHeaderConsumer(BasicOAuthStore base) {
addConsumer(
base,
GADGET_URL_HEADER,
FakeGadgetSpecFactory.SERVICE_NAME,
FakeOAuthServiceProvider.CONSUMER_KEY,
FakeOAuthServiceProvider.CONSUMER_SECRET);
}
private static void addBodyConsumer(BasicOAuthStore base) {
addConsumer(
base,
GADGET_URL_BODY,
FakeGadgetSpecFactory.SERVICE_NAME,
FakeOAuthServiceProvider.CONSUMER_KEY,
FakeOAuthServiceProvider.CONSUMER_SECRET);
}
private static void addConsumer(
BasicOAuthStore base,
String gadgetUrl,
String serviceName,
String consumerKey,
String consumerSecret) {
BasicOAuthStoreConsumerIndex providerKey = new BasicOAuthStoreConsumerIndex();
providerKey.setGadgetUri(gadgetUrl);
providerKey.setServiceName(serviceName);
BasicOAuthStoreConsumerKeyAndSecret kas = new BasicOAuthStoreConsumerKeyAndSecret(
consumerKey, consumerSecret, KeyType.HMAC_SYMMETRIC, null);
base.setConsumerKeyAndSecret(providerKey, kas);
}
private static void addDefaultKey(BasicOAuthStore base) {
BasicOAuthStoreConsumerKeyAndSecret defaultKey = new BasicOAuthStoreConsumerKeyAndSecret(
"signedfetch", FakeOAuthServiceProvider.PRIVATE_KEY_TEXT, KeyType.RSA_PRIVATE, "foo");
base.setDefaultKey(defaultKey);
}
/**
* Builds gadget token for testing a service with parameters in the query.
*/
public static SecurityToken getNormalSecurityToken(String owner, String viewer) throws Exception {
return getSecurityToken(owner, viewer, GADGET_URL);
}
/**
* Builds gadget token for testing services without a key.
*/
public static SecurityToken getNokeySecurityToken(String owner, String viewer) throws Exception {
return getSecurityToken(owner, viewer, GADGET_URL_NO_KEY);
}
/**
* Builds gadget token for testing a service that wants parameters in a header.
*/
public static SecurityToken getHeaderSecurityToken(String owner, String viewer) throws Exception {
return getSecurityToken(owner, viewer, GADGET_URL_HEADER);
}
/**
* Builds gadget token for testing a service that wants parameters in the request body.
*/
public static SecurityToken getBodySecurityToken(String owner, String viewer) throws Exception {
return getSecurityToken(owner, viewer, GADGET_URL_BODY);
}
public static SecurityToken getSecurityToken(String owner, String viewer, String gadget)
throws Exception {
return new BasicSecurityToken(owner, viewer, "app", "container.com", gadget, "0");
}
@After
public void tearDown() throws Exception {
}
/** Client that does OAuth and sends opensocial_* params */
private MakeRequestClient makeNonSocialClient(String owner, String viewer, String gadget)
throws Exception {
SecurityToken securityToken = getSecurityToken(owner, viewer, gadget);
MakeRequestClient client = new MakeRequestClient(securityToken, fetcherConfig, serviceProvider,
FakeGadgetSpecFactory.SERVICE_NAME);
client.getBaseArgs().setSignOwner(true);
client.getBaseArgs().setSignViewer(true);
return client;
}
/** Client that does OAuth and does not send opensocial_* params */
private MakeRequestClient makeStrictNonSocialClient(String owner, String viewer, String gadget)
throws Exception {
SecurityToken securityToken = getSecurityToken(owner, viewer, gadget);
return new MakeRequestClient(securityToken, fetcherConfig, serviceProvider,
FakeGadgetSpecFactory.SERVICE_NAME);
}
private MakeRequestClient makeSocialOAuthClient(String owner, String viewer, String gadget)
throws Exception {
SecurityToken securityToken = getSecurityToken(owner, viewer, gadget);
MakeRequestClient client = new MakeRequestClient(securityToken, fetcherConfig, serviceProvider,
FakeGadgetSpecFactory.SERVICE_NAME);
client.getBaseArgs().setUseToken(UseToken.IF_AVAILABLE);
return client;
}
private MakeRequestClient makeSignedFetchClient(String owner, String viewer, String gadget)
throws Exception {
SecurityToken securityToken = getSecurityToken(owner, viewer, gadget);
MakeRequestClient client = new MakeRequestClient(securityToken, fetcherConfig, serviceProvider,
null);
client.setBaseArgs(client.makeSignedFetchArguments());
return client;
}
@Test
public void testOAuthFlow() throws Exception {
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
checkEmptyLog();
}
@Test
public void testOAuthFlow_tokenReused() throws Exception {
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
// Check out what happens if the client-side oauth state vanishes.
MakeRequestClient client2 = makeNonSocialClient("owner", "owner", GADGET_URL);
response = client2.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
}
@Test
public void testOAuthFlow_unauthUser() throws Exception {
MakeRequestClient client = makeNonSocialClient(null, null, GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
assertEquals(403, response.getHttpStatusCode());
assertEquals(OAuthError.UNAUTHENTICATED.toString(), response.getMetadata().get("oauthError"));
}
@Test
public void testAccessTokenNotUsedForSocialPage() throws Exception {
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
MakeRequestClient friend = makeNonSocialClient("owner", "friend", GADGET_URL);
response = friend.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
assertEquals(403, response.getHttpStatusCode());
assertEquals(OAuthError.NOT_OWNER.toString(), response.getMetadata().get("oauthError"));
}
@Test
public void testParamsInHeader() throws Exception {
serviceProvider.setParamLocation(OAuthParamLocation.AUTH_HEADER);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL_HEADER);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
String aznHeader = response.getHeader(FakeOAuthServiceProvider.AUTHZ_ECHO_HEADER);
assertNotNull(aznHeader);
assertTrue("azn header: " + aznHeader, aznHeader.indexOf("OAuth") != -1);
}
@Test
public void testParamsInBody() throws Exception {
serviceProvider.setParamLocation(OAuthParamLocation.POST_BODY);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL_BODY);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendFormPost(FakeOAuthServiceProvider.RESOURCE_URL, "");
assertEquals("User data is hello-oauth", response.getResponseAsString());
String echoedBody = response.getHeader(FakeOAuthServiceProvider.BODY_ECHO_HEADER);
assertNotNull(echoedBody);
assertTrue("body: " + echoedBody, echoedBody.indexOf("oauth_consumer_key=") != -1);
}
@Test
public void testParamsInBody_withExtraParams() throws Exception {
serviceProvider.setParamLocation(OAuthParamLocation.POST_BODY);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL_BODY);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendFormPost(FakeOAuthServiceProvider.RESOURCE_URL, "foo=bar&foo=baz");
assertEquals("User data is hello-oauth", response.getResponseAsString());
String echoedBody = response.getHeader(FakeOAuthServiceProvider.BODY_ECHO_HEADER);
assertNotNull(echoedBody);
assertTrue("body: " + echoedBody, echoedBody.indexOf("oauth_consumer_key=") != -1);
assertTrue("body: " + echoedBody, echoedBody.indexOf("foo=bar&foo=baz") != -1);
}
@Test
public void testParamsInBody_forGetRequest() throws Exception {
serviceProvider.setParamLocation(OAuthParamLocation.POST_BODY);
serviceProvider.addParamLocation(OAuthParamLocation.AUTH_HEADER);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL_BODY);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
String aznHeader = response.getHeader(FakeOAuthServiceProvider.AUTHZ_ECHO_HEADER);
assertNotNull(aznHeader);
assertTrue("azn header: " + aznHeader, aznHeader.indexOf("OAuth") != -1);
}
@Test
public void testParamsInBody_forGetRequestStrictSp() throws Exception {
serviceProvider.setParamLocation(OAuthParamLocation.POST_BODY);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL_BODY);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
assertNotNull(response.getMetadata().get("oauthApprovalUrl"));
}
@Test
public void testRevokedAccessToken() throws Exception {
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=1");
assertEquals("User data is hello-oauth", response.getResponseAsString());
serviceProvider.revokeAllAccessTokens();
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=2");
assertEquals("", response.getResponseAsString());
assertNotNull(response.getMetadata().get("oauthApprovalUrl"));
client.approveToken("user_data=reapproved");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=3");
assertEquals("User data is reapproved", response.getResponseAsString());
}
@Test
public void testError401() throws Exception {
serviceProvider.setVagueErrors(true);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=1");
assertEquals("User data is hello-oauth", response.getResponseAsString());
serviceProvider.revokeAllAccessTokens();
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=2");
checkLogContains("GET /data?cachebust=2");
checkLogContains("HTTP/1.1 401");
assertEquals("", response.getResponseAsString());
assertNotNull(response.getMetadata().get("oauthApprovalUrl"));
client.approveToken("user_data=reapproved");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=3");
assertEquals("User data is reapproved", response.getResponseAsString());
}
@Test
public void testUnknownConsumerKey() throws Exception {
SecurityToken securityToken = getSecurityToken("owner", "owner", GADGET_URL_NO_KEY);
MakeRequestClient client = new MakeRequestClient(securityToken, fetcherConfig, serviceProvider,
FakeGadgetSpecFactory.SERVICE_NAME_NO_KEY);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
Map<String, String> metadata = response.getMetadata();
assertNotNull(metadata);
assertEquals("consumer_key_unknown", metadata.get("oauthError"));
assertEquals(
"invalid consumer: garbage_key",
metadata.get("oauthErrorText"));
}
@Test
public void testError403() throws Exception {
serviceProvider.setVagueErrors(true);
SecurityToken securityToken = getSecurityToken("owner", "owner", GADGET_URL_NO_KEY);
MakeRequestClient client = new MakeRequestClient(securityToken, fetcherConfig, serviceProvider,
FakeGadgetSpecFactory.SERVICE_NAME_NO_KEY);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
Map<String, String> metadata = response.getMetadata();
assertNotNull(metadata);
assertEquals("403", metadata.get("oauthError"));
assertNull(metadata.get("oauthErrorText"));
checkLogContains("HTTP/1.1 403");
checkLogContains("GET /request");
checkLogContains("some vague error");
}
@Test
public void testError404() throws Exception {
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=1");
assertEquals("User data is hello-oauth", response.getResponseAsString());
response = client.sendGet(FakeOAuthServiceProvider.NOT_FOUND_URL);
assertEquals("not found", response.getResponseAsString());
assertEquals(404, response.getHttpStatusCode());
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=3");
assertEquals("User data is hello-oauth", response.getResponseAsString());
}
@Test
public void testConsumerThrottled() throws Exception {
assertEquals(0, serviceProvider.getRequestTokenCount());
assertEquals(0, serviceProvider.getAccessTokenCount());
assertEquals(0, serviceProvider.getResourceAccessCount());
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(0, serviceProvider.getAccessTokenCount());
assertEquals(0, serviceProvider.getResourceAccessCount());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=1");
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(2, serviceProvider.getResourceAccessCount());
serviceProvider.setConsumersThrottled(true);
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=2");
assertEquals("", response.getResponseAsString());
Map<String, String> metadata = response.getMetadata();
assertNotNull(metadata);
assertEquals("consumer_key_refused", metadata.get("oauthError"));
assertEquals(
"exceeded quota",
metadata.get("oauthErrorText"));
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(3, serviceProvider.getResourceAccessCount());
serviceProvider.setConsumersThrottled(false);
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=3");
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(4, serviceProvider.getResourceAccessCount());
}
@Test
public void testSocialOAuth_tokenRevoked() throws Exception {
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
serviceProvider.revokeAllAccessTokens();
assertEquals(0, base.getAccessTokenRemoveCount());
client = makeSocialOAuthClient("owner", "owner", GADGET_URL);
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=1");
assertEquals("", response.getResponseAsString());
assertEquals(1, base.getAccessTokenRemoveCount());
}
@Test
public void testWrongServiceName() throws Exception {
SecurityToken securityToken = getSecurityToken("owner", "owner", GADGET_URL);
MakeRequestClient client = new MakeRequestClient(securityToken, fetcherConfig, serviceProvider,
"nosuchservice");
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
Map<String, String> metadata = response.getMetadata();
assertNull(metadata.get("oauthApprovalUrl"));
assertEquals("BAD_OAUTH_CONFIGURATION", metadata.get("oauthError"));
String errorText = metadata.get("oauthErrorText");
assertTrue(errorText, errorText.startsWith(
"Spec for gadget http://www.example.com/gadget.xml does not contain OAuth service " +
"nosuchservice. Known services: testservice"));
}
@Test
public void testPreapprovedToken() throws Exception {
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
TokenPair reqToken = serviceProvider.getPreapprovedToken("preapproved");
client.getBaseArgs().setRequestToken(reqToken.token);
client.getBaseArgs().setRequestTokenSecret(reqToken.secret);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is preapproved", response.getResponseAsString());
assertEquals(0, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=1");
assertEquals("User data is preapproved", response.getResponseAsString());
assertEquals(0, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(2, serviceProvider.getResourceAccessCount());
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=2");
assertEquals("User data is preapproved", response.getResponseAsString());
assertEquals(0, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(3, serviceProvider.getResourceAccessCount());
}
@Test
public void testPreapprovedToken_invalid() throws Exception {
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
client.getBaseArgs().setRequestToken("garbage");
client.getBaseArgs().setRequestTokenSecret("garbage");
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(0, serviceProvider.getResourceAccessCount());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(2, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
}
@Test
public void testPreapprovedToken_notUsedIfAccessTokenExists() throws Exception {
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
TokenPair reqToken = serviceProvider.getPreapprovedToken("preapproved");
client.getBaseArgs().setRequestToken(reqToken.token);
client.getBaseArgs().setRequestTokenSecret(reqToken.secret);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is preapproved", response.getResponseAsString());
assertEquals(0, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
MakeRequestClient client2 = makeNonSocialClient("owner", "owner", GADGET_URL);
response = client2.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cachebust=1");
assertEquals("User data is preapproved", response.getResponseAsString());
assertEquals(0, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(2, serviceProvider.getResourceAccessCount());
}
@Test
public void testCachedResponse() throws Exception {
assertEquals(0, serviceProvider.getRequestTokenCount());
assertEquals(0, serviceProvider.getAccessTokenCount());
assertEquals(0, serviceProvider.getResourceAccessCount());
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
}
@Test
public void testSignedFetchParametersSet() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "opensocial_owner_id", "o"));
assertTrue(contains(queryParams, "opensocial_viewer_id", "v"));
assertTrue(contains(queryParams, "opensocial_app_id", "app"));
assertTrue(contains(queryParams, OAuth.OAUTH_CONSUMER_KEY, "signedfetch"));
assertTrue(contains(queryParams, "xoauth_signature_publickey", "foo"));
}
@Test
public void testPostBinaryData() throws Exception {
byte[] raw = new byte[] { 0, 1, 2, 3, 4, 5 };
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendRawPost(FakeOAuthServiceProvider.RESOURCE_URL, null, raw);
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "opensocial_owner_id", "o"));
assertTrue(contains(queryParams, OAuth.OAUTH_CONSUMER_KEY, "signedfetch"));
String echoed = resp.getHeader(FakeOAuthServiceProvider.RAW_BODY_ECHO_HEADER);
byte[] echoedBytes = Base64.decodeBase64(CharsetUtil.getUtf8Bytes(echoed));
assertTrue(Arrays.equals(raw, echoedBytes));
}
@Test
public void testPostWeirdContentType() throws Exception {
byte[] raw = new byte[] { 0, 1, 2, 3, 4, 5 };
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendRawPost(FakeOAuthServiceProvider.RESOURCE_URL,
"funky-content", raw);
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "opensocial_owner_id", "o"));
assertTrue(contains(queryParams, OAuth.OAUTH_CONSUMER_KEY, "signedfetch"));
String echoed = resp.getHeader(FakeOAuthServiceProvider.RAW_BODY_ECHO_HEADER);
byte[] echoedBytes = Base64.decodeBase64(CharsetUtil.getUtf8Bytes(echoed));
assertTrue(Arrays.equals(raw, echoedBytes));
}
@Test
public void testSignedFetch_error401() throws Exception {
assertEquals(0, base.getAccessTokenRemoveCount());
serviceProvider.setConsumersThrottled(true);
serviceProvider.setVagueErrors(true);
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals(0, base.getAccessTokenRemoveCount());
}
@Test
public void testSignedFetch_unnamedConsumerKey() throws Exception {
BasicOAuthStoreConsumerKeyAndSecret defaultKey = new BasicOAuthStoreConsumerKeyAndSecret(
null, FakeOAuthServiceProvider.PRIVATE_KEY_TEXT, KeyType.RSA_PRIVATE, "foo");
base.setDefaultKey(defaultKey);
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "opensocial_owner_id", "o"));
assertTrue(contains(queryParams, "opensocial_viewer_id", "v"));
assertTrue(contains(queryParams, "opensocial_app_id", "app"));
assertTrue(contains(queryParams, OAuth.OAUTH_CONSUMER_KEY, "container.com"));
assertTrue(contains(queryParams, "xoauth_signature_publickey", "foo"));
}
@Test
public void testSignedFetch_extraQueryParameters() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?foo=bar&foo=baz");
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "opensocial_owner_id", "o"));
assertTrue(contains(queryParams, "opensocial_viewer_id", "v"));
assertTrue(contains(queryParams, "opensocial_app_id", "app"));
assertTrue(contains(queryParams, OAuth.OAUTH_CONSUMER_KEY, "signedfetch"));
assertTrue(contains(queryParams, "xoauth_signature_publickey", "foo"));
}
@Test
public void testNoSignViewer() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client.getBaseArgs().setSignViewer(false);
HttpResponse resp = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "opensocial_owner_id", "o"));
assertFalse(contains(queryParams, "opensocial_viewer_id", "v"));
}
@Test
public void testNoSignOwner() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client.getBaseArgs().setSignOwner(false);
HttpResponse resp = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertFalse(contains(queryParams, "opensocial_owner_id", "o"));
assertTrue(contains(queryParams, "opensocial_viewer_id", "v"));
}
@Test
public void testCacheHit() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals(1, serviceProvider.getResourceAccessCount());
client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals(1, serviceProvider.getResourceAccessCount());
}
@Test
public void testCacheMiss_noOwner() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client.getBaseArgs().setSignOwner(false);
client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals(1, serviceProvider.getResourceAccessCount());
MakeRequestClient client2 = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client2.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals(2, serviceProvider.getResourceAccessCount());
}
@Test
public void testCacheHit_ownerOnly() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v1", "http://www.example.com/app");
client.getBaseArgs().setSignViewer(false);
client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals(1, serviceProvider.getResourceAccessCount());
MakeRequestClient client2 = makeSignedFetchClient("o", "v2", "http://www.example.com/app");
client2.getBaseArgs().setSignViewer(false);
client2.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals(1, serviceProvider.getResourceAccessCount());
}
@Test
public void testCacheMiss_bypassCache() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v1", "http://www.example.com/app");
client.getBaseArgs().setSignViewer(false);
client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals(1, serviceProvider.getResourceAccessCount());
MakeRequestClient client2 = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client2.setIgnoreCache(true);
client2.getBaseArgs().setSignViewer(false);
client2.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals(2, serviceProvider.getResourceAccessCount());
}
@Test(expected = RequestSigningException.class)
public void testTrickyParametersInQuery() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
String tricky = "%6fpensocial_owner_id=gotcha";
client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?" + tricky);
}
@Test(expected = RequestSigningException.class)
public void testTrickyParametersInBody() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
String tricky = "%6fpensocial_owner_id=gotcha";
client.sendFormPost(FakeOAuthServiceProvider.RESOURCE_URL, tricky);
}
@Test
public void testGetNoQuery() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "opensocial_owner_id", "o"));
assertTrue(contains(queryParams, "opensocial_viewer_id", "v"));
}
@Test
public void testGetWithQuery() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?a=b");
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "a", "b"));
}
@Test
public void testGetWithQueryMultiParam() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?a=b&a=c");
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "a", "b"));
assertTrue(contains(queryParams, "a", "c"));
}
@Test
public void testValidParameterCharacters() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
String weird = "~!@$*()-_[]:,./";
HttpResponse resp = client.sendGet(
FakeOAuthServiceProvider.RESOURCE_URL + "?" + weird + "=foo");
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, weird, "foo"));
}
@Test
public void testPostNoQueryNoData() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendFormPost(FakeOAuthServiceProvider.RESOURCE_URL, null);
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "opensocial_owner_id", "o"));
assertEquals("", resp.getHeader(FakeOAuthServiceProvider.BODY_ECHO_HEADER));
}
@Test
public void testPostWithQueryNoData() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendFormPost(
FakeOAuthServiceProvider.RESOURCE_URL + "?name=value", null);
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "name", "value"));
assertEquals("", resp.getHeader(FakeOAuthServiceProvider.BODY_ECHO_HEADER));
}
@Test
public void testPostNoQueryWithData() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendFormPost(
FakeOAuthServiceProvider.RESOURCE_URL, "name=value");
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertFalse(contains(queryParams, "name", "value"));
assertEquals("name=value", resp.getHeader(FakeOAuthServiceProvider.BODY_ECHO_HEADER));
}
@Test
public void testPostWithQueryWithData() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
HttpResponse resp = client.sendFormPost(
FakeOAuthServiceProvider.RESOURCE_URL + "?queryName=queryValue", "name=value");
List<Parameter> queryParams = OAuth.decodeForm(resp.getResponseAsString());
assertTrue(contains(queryParams, "queryName", "queryValue"));
assertEquals("name=value", resp.getHeader(FakeOAuthServiceProvider.BODY_ECHO_HEADER));
}
@Test(expected = RequestSigningException.class)
public void testStripOpenSocialParamsFromQuery() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client.sendFormPost(FakeOAuthServiceProvider.RESOURCE_URL + "?opensocial_foo=bar", null);
}
@Test(expected = RequestSigningException.class)
public void testStripOAuthParamsFromQuery() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client.sendFormPost(FakeOAuthServiceProvider.RESOURCE_URL + "?oauth_foo=bar", "name=value");
}
@Test(expected = RequestSigningException.class)
public void testStripOpenSocialParamsFromBody() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client.sendFormPost(FakeOAuthServiceProvider.RESOURCE_URL, "opensocial_foo=bar");
}
@Test(expected = RequestSigningException.class)
public void testStripOAuthParamsFromBody() throws Exception {
MakeRequestClient client = makeSignedFetchClient("o", "v", "http://www.example.com/app");
client.sendFormPost(FakeOAuthServiceProvider.RESOURCE_URL, "oauth_foo=bar");
}
// Test we can refresh an expired access token.
@Test
public void testAccessTokenExpires_onClient() throws Exception {
serviceProvider.setSessionExtension(true);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
clock.incrementSeconds(FakeOAuthServiceProvider.TOKEN_EXPIRATION_SECONDS + 1);
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=1");
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(2, serviceProvider.getAccessTokenCount());
assertEquals(2, serviceProvider.getResourceAccessCount());
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=3");
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(2, serviceProvider.getAccessTokenCount());
assertEquals(3, serviceProvider.getResourceAccessCount());
clock.incrementSeconds(FakeOAuthServiceProvider.TOKEN_EXPIRATION_SECONDS + 1);
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=4");
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(3, serviceProvider.getAccessTokenCount());
assertEquals(4, serviceProvider.getResourceAccessCount());
}
// Tests the case where the server doesn't tell us when the token will expire. This requires
// an extra round trip to discover that the token has expired.
@Test
public void testAccessTokenExpires_onClientNoPredictedExpiration() throws Exception {
serviceProvider.setSessionExtension(true);
serviceProvider.setReportExpirationTimes(false);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
clock.incrementSeconds(FakeOAuthServiceProvider.TOKEN_EXPIRATION_SECONDS + 1);
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=1");
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(2, serviceProvider.getAccessTokenCount());
assertEquals(3, serviceProvider.getResourceAccessCount());
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=3");
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(2, serviceProvider.getAccessTokenCount());
assertEquals(4, serviceProvider.getResourceAccessCount());
clock.incrementSeconds(FakeOAuthServiceProvider.TOKEN_EXPIRATION_SECONDS + 1);
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=4");
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(3, serviceProvider.getAccessTokenCount());
assertEquals(6, serviceProvider.getResourceAccessCount());
}
@Test
public void testAccessTokenExpires_onServer() throws Exception {
serviceProvider.setSessionExtension(true);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
// clears oauthState
client = makeNonSocialClient("owner", "owner", GADGET_URL);
clock.incrementSeconds(FakeOAuthServiceProvider.TOKEN_EXPIRATION_SECONDS + 1);
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=1");
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(2, serviceProvider.getAccessTokenCount());
assertEquals(2, serviceProvider.getResourceAccessCount());
}
@Test
public void testAccessTokenExpired_andRevoked() throws Exception {
serviceProvider.setSessionExtension(true);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
clock.incrementSeconds(FakeOAuthServiceProvider.TOKEN_EXPIRATION_SECONDS + 1);
serviceProvider.revokeAllAccessTokens();
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=1");
assertEquals("", response.getResponseAsString());
assertEquals(2, serviceProvider.getRequestTokenCount());
assertEquals(2, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
client.approveToken("user_data=renewed");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=1");
assertEquals(2, serviceProvider.getRequestTokenCount());
assertEquals(3, serviceProvider.getAccessTokenCount());
assertEquals(2, serviceProvider.getResourceAccessCount());
assertEquals("User data is renewed", response.getResponseAsString());
}
@Test
public void testBadSessionHandle() throws Exception {
serviceProvider.setSessionExtension(true);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
assertEquals(1, serviceProvider.getRequestTokenCount());
assertEquals(1, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
clock.incrementSeconds(FakeOAuthServiceProvider.TOKEN_EXPIRATION_SECONDS + 1);
serviceProvider.changeAllSessionHandles();
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=1");
assertEquals("", response.getResponseAsString());
assertEquals(2, serviceProvider.getRequestTokenCount());
assertEquals(2, serviceProvider.getAccessTokenCount());
assertEquals(1, serviceProvider.getResourceAccessCount());
client.approveToken("user_data=renewed");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL + "?cb=1");
assertEquals(2, serviceProvider.getRequestTokenCount());
assertEquals(3, serviceProvider.getAccessTokenCount());
assertEquals(2, serviceProvider.getResourceAccessCount());
assertEquals("User data is renewed", response.getResponseAsString());
}
@Test
public void testExtraParamsRejected() throws Exception {
serviceProvider.setRejectExtraParams(true);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("parameter_rejected", response.getMetadata().get("oauthError"));
}
@Test
public void testExtraParamsSuppressed() throws Exception {
serviceProvider.setRejectExtraParams(true);
MakeRequestClient client = makeStrictNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
}
@Test
public void testCanRetrieveAccessTokenData() throws Exception {
serviceProvider.setReturnAccessTokenData(true);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.ACCESS_TOKEN_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.ACCESS_TOKEN_URL);
assertEquals("application/json; charset=utf-8", response.getHeader("Content-Type"));
JSONObject json = new JSONObject(response.getResponseAsString());
assertEquals("userid value", json.get("userid"));
assertEquals("xoauth_stuff value", json.get("xoauth_stuff"));
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
}
@Test
public void testAccessTokenData_noOAuthParams() throws Exception {
serviceProvider.setReturnAccessTokenData(true);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.ACCESS_TOKEN_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.ACCESS_TOKEN_URL);
JSONObject json = new JSONObject(response.getResponseAsString());
assertEquals("userid value", json.get("userid"));
assertEquals("xoauth_stuff value", json.get("xoauth_stuff"));
assertEquals(2, json.length());
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
}
@Test
public void testAccessTokenData_noDirectRequest() throws Exception {
serviceProvider.setReturnAccessTokenData(true);
MakeRequestClient client = makeNonSocialClient("owner", "owner", GADGET_URL);
HttpResponse response = client.sendGet(FakeOAuthServiceProvider.ACCESS_TOKEN_URL);
assertEquals("", response.getResponseAsString());
client.approveToken("user_data=hello-oauth");
response = client.sendGet(FakeOAuthServiceProvider.RESOURCE_URL);
assertEquals("User data is hello-oauth", response.getResponseAsString());
response = client.sendGet(FakeOAuthServiceProvider.ACCESS_TOKEN_URL);
assertEquals("", response.getResponseAsString());
assertTrue(response.getMetadata().containsKey("oauthApprovalUrl"));
}
// Checks whether the given parameter list contains the specified
// key/value pair
private boolean contains(List<Parameter> params, String key, String value) {
for (Parameter p : params) {
if (p.getKey().equals(key) && p.getValue().equals(value)) {
return true;
}
}
return false;
}
private String getLogText() {
StringBuilder logText = new StringBuilder();
for (LogRecord record : logRecords) {
logText.append(record.getMessage());
}
return logText.toString();
}
private void checkLogContains(String text) {
if ((logger.getLevel()!=null)&&(logger.getLevel().equals(Level.OFF))) {
return;
}
String logText = getLogText();
if (!logText.contains(text)) {
fail("Should have logged '" + text + "', instead got " + logText);
}
}
private void checkEmptyLog() {
assertEquals("", getLogText());
}
}