2 Commits
Author SHA1 Message Date
krogoth 0386df2606 Fix for basestring URI not properly encoded regarding RFC5849 ch 3.4.1.2
This will prevent failure for non standard port and uppercase host or scheme strings
Added related test cases.

Warning : Request constructor signature changed. A java.net.MalformedURLException exception will be throw when creating a request if not a proper URL
previously this cannot occur until send.
2011-02-03 16:48:11 +01:00
krogoth ca0076c043 Refactored scribe 1.1.0 to handdle properly encodings as per RFC5849. This is the first try for comment. 2011-02-03 00:03:45 +01:00
52 changed files with 360 additions and 854 deletions

No files matched your search

+4 -4
View File
@@ -1,3 +1,5 @@
!http://img411.imageshack.us/img411/2851/scribelogo.png!
h2. Welcome to the home of Scribe, the simple OAuth Java lib! h2. Welcome to the home of Scribe, the simple OAuth Java lib!
h1. Why use Scribe? h1. Why use Scribe?
@@ -18,12 +20,10 @@ h3. Threadsafe
Hit Scribe as hard and with many threads as you like. Hit Scribe as hard and with many threads as you like.
h3. Supports all major 1.0a and 2.0 OAuth APIs out-of-the-box h3. Supports all major OAuth APIs out-of-the-box
* Google * Google
* Facebook
* Yahoo * Yahoo
* LinkedIn * LinkedIn
@@ -61,7 +61,7 @@ You can pull scribe from a maven repository, just add this to your __pom.xml__ f
@<dependency>@ @<dependency>@
@<groupId>org.scribe</groupId>@ @<groupId>org.scribe</groupId>@
@<artifactId>scribe</artifactId>@ @<artifactId>scribe</artifactId>@
@<version>1.2.0</version>@ @<version>1.0.6</version>@
@</dependency>@ @</dependency>@
h1. Getting started in less than 2 minutes h1. Getting started in less than 2 minutes
-2
View File
@@ -1,2 +0,0 @@
#!/bin/sh
mvn source:jar javadoc:jar package gpg:sign repository:bundle-create -Dgpg.passphrase=$1
+1 -22
View File
@@ -28,25 +28,4 @@
[1.1.1] [1.1.1]
* FIX: Removed isEmpty() from OAuth2.0 code in order to support older JVMs * FIX: Removed isEmpty() from OAuth2.0 code in order to support older JVMs
* FEATURE: Overloaded provider() method to support instances as well as classes (thanks dustismo) * FEATURE: Overloaded provider() method to support instances as well as classes (thanks dustismo)
* FIX: White-space parameter bug (thanks Krogoth)
* FEATURE: OAuth 2.0 now implements server-flow (thanks Diego Silveira)
[1.1.2]
* FIX: Fixed ugly bug that made 1.1.1 practically unusable (thanks Stubbs)
[1.1.3]
* FEATURE: Added rawResponse to Token, for extracting additional parameters (thanks Dirk McCormick)
* FEATURE: Added Dropbox Api
* FIX: Token responses now work despite of the token/secret order
* FEATURE: Added Foursquare OAuth 2.0 Api (thanks Tom Tasche)
* FEATURE: Added support for OAuth1.0a signatures via querystring parameters
* FEATURE: Added ConstantContact Api (thanks Matthew Laudato)
[1.2]
* REFACTOR: Moved scope inside OAuthConfig (breaks backwards compatibility)
* FEATURE: Added scopes to Facebook 2.0 Api
* FEATURE: Added Plaintext signature for Yammer
* FEATURE: Added Twitter SSL endpoints (use TwitterApi.SSL.class)
+1 -1
View File
@@ -4,7 +4,7 @@
<groupId>org.scribe</groupId> <groupId>org.scribe</groupId>
<artifactId>scribe</artifactId> <artifactId>scribe</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.2.0</version> <version>1.1.0</version>
<name>Scribe OAuth Library</name> <name>Scribe OAuth Library</name>
<description>The best OAuth library out there</description> <description>The best OAuth library out there</description>
<url>http://github.com/fernandezpablo85/scribe-java</url> <url>http://github.com/fernandezpablo85/scribe-java</url>
@@ -20,7 +20,6 @@ public class ServiceBuilder
private String callback; private String callback;
private Api api; private Api api;
private String scope; private String scope;
private SignatureType signatureType;
/** /**
* Default constructor * Default constructor
@@ -123,19 +122,6 @@ public class ServiceBuilder
this.scope = scope; this.scope = scope;
return this; return this;
} }
/**
* Configures the signature type, choose between header, querystring, etc. Defaults to Header
*
* @param scope The OAuth scope
* @return the {@link ServiceBuilder} instance for method chaining
*/
public ServiceBuilder signatureType(SignatureType type)
{
Preconditions.checkNotNull(type, "Signature type can't be null");
this.signatureType = type;
return this;
}
/** /**
* Returns the fully configured {@link OAuthService} * Returns the fully configured {@link OAuthService}
@@ -147,6 +133,6 @@ public class ServiceBuilder
Preconditions.checkNotNull(api, "You must specify a valid api through the provider() method"); Preconditions.checkNotNull(api, "You must specify a valid api through the provider() method");
Preconditions.checkEmptyString(apiKey, "You must provide an api key"); Preconditions.checkEmptyString(apiKey, "You must provide an api key");
Preconditions.checkEmptyString(apiSecret, "You must provide an api secret"); Preconditions.checkEmptyString(apiSecret, "You must provide an api secret");
return api.createService(new OAuthConfig(apiKey, apiSecret, callback, signatureType, scope)); return api.createService(new OAuthConfig(apiKey, apiSecret, callback), scope);
} }
} }
@@ -21,5 +21,5 @@ public interface Api
* *
* @return fully configured {@link OAuthService} * @return fully configured {@link OAuthService}
*/ */
OAuthService createService(OAuthConfig config); OAuthService createService(OAuthConfig config, String scope);
} }
@@ -1,26 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.*;
public class ConstantContactApi extends DefaultApi10a
{
private static final String AUTHORIZE_URL = "https://oauth.constantcontact.com/ws/oauth/confirm_access?oauth_token=%s";
@Override
public String getAccessTokenEndpoint()
{
return "https://oauth.constantcontact.com/ws/oauth/access_token";
}
@Override
public String getAuthorizationUrl(Token requestToken)
{
return String.format(AUTHORIZE_URL, requestToken.getToken());
}
@Override
public String getRequestTokenEndpoint()
{
return "https://oauth.constantcontact.com/ws/oauth/request_token";
}
}
@@ -134,7 +134,14 @@ public abstract class DefaultApi10a implements Api
* @param callback OAuth callback (either URL or 'oob') * @param callback OAuth callback (either URL or 'oob')
* @param scope OAuth scope (optional) * @param scope OAuth scope (optional)
*/ */
public OAuthService createService(OAuthConfig config) public OAuthService createService(OAuthConfig config, String scope)
{
OAuthService service = doCreateService(config);
service.addScope(scope);
return service;
}
private OAuthService doCreateService(OAuthConfig config)
{ {
return new OAuth10aServiceImpl(this, config); return new OAuth10aServiceImpl(this, config);
} }
@@ -1,6 +1,5 @@
package org.scribe.builder.api; package org.scribe.builder.api;
import org.scribe.extractors.*;
import org.scribe.model.*; import org.scribe.model.*;
import org.scribe.oauth.*; import org.scribe.oauth.*;
@@ -23,33 +22,6 @@ import org.scribe.oauth.*;
public abstract class DefaultApi20 implements Api public abstract class DefaultApi20 implements Api
{ {
/**
* Returns the access token extractor.
*
* @return access token extractor
*/
public AccessTokenExtractor getAccessTokenExtractor()
{
return new TokenExtractor20Impl();
}
/**
* Returns the verb for the access token endpoint (defaults to GET)
*
* @return access token endpoint verb
*/
public Verb getAccessTokenVerb()
{
return Verb.GET;
}
/**
* Returns the URL that receives the access token requests.
*
* @return access token URL
*/
public abstract String getAccessTokenEndpoint();
/** /**
* Returns the URL where you should redirect your users to authenticate * Returns the URL where you should redirect your users to authenticate
* your application. * your application.
@@ -62,7 +34,7 @@ public abstract class DefaultApi20 implements Api
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public OAuthService createService(OAuthConfig config) public OAuthService createService(OAuthConfig config, String scope)
{ {
return new OAuth20ServiceImpl(this, config); return new OAuth20ServiceImpl(this, config);
} }
@@ -1,25 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.*;
public class DropBoxApi extends DefaultApi10a
{
@Override
public String getAccessTokenEndpoint()
{
return "https://api.dropbox.com/0/oauth/access_token";
}
@Override
public String getAuthorizationUrl(Token requestToken)
{
return "https://www.dropbox.com/0/oauth/authorize?oauth_token="+requestToken.getToken();
}
@Override
public String getRequestTokenEndpoint()
{
return "https://api.dropbox.com/0/oauth/request_token";
}
}
@@ -1,34 +1,16 @@
package org.scribe.builder.api; package org.scribe.builder.api;
import org.scribe.model.*; import org.scribe.model.*;
import org.scribe.utils.*; import org.scribe.utils.*;
import static org.scribe.utils.URLUtils.*;
public class FacebookApi extends DefaultApi20 public class FacebookApi extends DefaultApi20
{ {
private static final String AUTHORIZE_URL = "https://www.facebook.com/dialog/oauth?client_id=%s&redirect_uri=%s"; private static final String AUTHORIZE_URL = "https://graph.facebook.com/oauth/authorize?response_type=token&client_id=%s&redirect_uri=%s";
private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s";
@Override
public String getAccessTokenEndpoint()
{
return "https://graph.facebook.com/oauth/access_token";
}
@Override @Override
public String getAuthorizationUrl(OAuthConfig config) public String getAuthorizationUrl(OAuthConfig config)
{ {
Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Facebook does not support OOB"); Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Facebook does not support OOB");
return String.format(AUTHORIZE_URL, config.getApiKey(), URLUtils.urlEncodeWrapper(config.getCallback()));
// Append scope if present
if(config.hasScope())
{
return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), formURLEncode(config.getCallback()), formURLEncode(config.getScope()));
}
else
{
return String.format(AUTHORIZE_URL, config.getApiKey(), formURLEncode(config.getCallback()));
}
} }
} }
@@ -1,29 +0,0 @@
package org.scribe.builder.api;
import org.scribe.extractors.*;
import org.scribe.model.*;
import org.scribe.utils.*;
public class Foursquare2Api extends DefaultApi20
{
private static final String AUTHORIZATION_URL = "https://foursquare.com/oauth2/authenticate?client_id=%s&response_type=code&redirect_uri=%s";
@Override
public String getAccessTokenEndpoint()
{
return "https://foursquare.com/oauth2/access_token?grant_type=authorization_code";
}
@Override
public String getAuthorizationUrl(OAuthConfig config)
{
Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Foursquare2 does not support OOB");
return String.format(AUTHORIZATION_URL, config.getApiKey(), URLUtils.formURLEncode(config.getCallback()));
}
@Override
public AccessTokenExtractor getAccessTokenExtractor()
{
return new JsonTokenExtractor();
}
}
@@ -1,28 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.Token;
public class LoveFilmApi extends DefaultApi10a
{
private static final String REQUEST_TOKEN_URL = "http://openapi.lovefilm.com/oauth/request_token";
private static final String ACCESS_TOKEN_URL = "http://openapi.lovefilm.com/oauth/access_token";
private static final String AUTHORIZE_URL = "https://www.lovefilm.com/activate?oauth_token=%s";
@Override
public String getRequestTokenEndpoint()
{
return REQUEST_TOKEN_URL;
}
@Override
public String getAccessTokenEndpoint()
{
return ACCESS_TOKEN_URL;
}
@Override
public String getAuthorizationUrl(Token requestToken)
{
return String.format(AUTHORIZE_URL, requestToken.getToken());
}
}
@@ -5,39 +5,22 @@ import org.scribe.model.Token;
public class TwitterApi extends DefaultApi10a public class TwitterApi extends DefaultApi10a
{ {
private static final String AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize?oauth_token=%s"; private static final String AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize?oauth_token=%s";
private static final String REQUEST_TOKEN_RESOURCE = "api.twitter.com/oauth/request_token";
private static final String ACCESS_TOKEN_RESOURCE = "api.twitter.com/oauth/access_token";
@Override @Override
public String getAccessTokenEndpoint() public String getAccessTokenEndpoint()
{ {
return "http://" + ACCESS_TOKEN_RESOURCE; return "http://api.twitter.com/oauth/access_token";
} }
@Override @Override
public String getRequestTokenEndpoint() public String getRequestTokenEndpoint()
{ {
return "http://" + REQUEST_TOKEN_RESOURCE; return "http://api.twitter.com/oauth/request_token";
} }
@Override @Override
public String getAuthorizationUrl(Token requestToken) public String getAuthorizationUrl(Token requestToken)
{ {
return String.format(AUTHORIZE_URL, requestToken.getToken()); return String.format(AUTHORIZE_URL, requestToken.getToken());
} }
public static class SSL extends TwitterApi
{
@Override
public String getAccessTokenEndpoint()
{
return "https://" + ACCESS_TOKEN_RESOURCE;
}
@Override
public String getRequestTokenEndpoint()
{
return "https://" + REQUEST_TOKEN_RESOURCE;
}
}
} }
@@ -1,33 +1,26 @@
package org.scribe.builder.api; package org.scribe.builder.api;
import org.scribe.model.*; import org.scribe.model.Token;
import org.scribe.services.*;
public class YammerApi extends DefaultApi10a public class YammerApi extends DefaultApi10a
{ {
private static final String AUTHORIZATION_URL = "'https://www.yammer.com/oauth/authorize?oauth_token=%s'"; private static final String AUTHORIZATION_URL = "'https://www.yammer.com/oauth/authorize?oauth_token=%s'";
@Override @Override
public String getRequestTokenEndpoint() public String getRequestTokenEndpoint()
{ {
return "https://www.yammer.com/oauth/request_token"; return "https://www.yammer.com/oauth/request_token";
} }
@Override @Override
public String getAccessTokenEndpoint() public String getAccessTokenEndpoint()
{ {
return "https://www.yammer.com/oauth/access_token"; return "https://www.yammer.com/oauth/access_token";
} }
@Override @Override
public String getAuthorizationUrl(Token requestToken) public String getAuthorizationUrl(Token requestToken)
{ {
return String.format(AUTHORIZATION_URL, requestToken.getToken()); return String.format(AUTHORIZATION_URL, requestToken.getToken());
} }
@Override
public SignatureService getSignatureService()
{
return new PlaintextSignatureService();
}
} }
@@ -32,9 +32,29 @@ public class BaseStringExtractorImpl implements BaseStringExtractor
private String getSortedAndEncodedParams(OAuthRequest request) private String getSortedAndEncodedParams(OAuthRequest request)
{ {
Map<String, String> params = new HashMap<String, String>(); Map<String, String> params = new HashMap<String, String>();
MapUtils.decodeAndAppendEntries(request.getQueryStringParams(), params); Map<String, String> tmp = null;
MapUtils.decodeAndAppendEntries(request.getBodyParams(), params); //params.putAll(request.getQueryStringParams());
MapUtils.decodeAndAppendEntries(request.getOauthParameters(), params); tmp = request.getQueryStringParams();
for (String key:tmp.keySet()){
params.put(
URLUtils.percentEncode(key),
URLUtils.percentEncode(tmp.get(key))
);
}
tmp = request.getBodyParams();
for (String key:tmp.keySet()){
params.put(
URLUtils.percentEncode(key),
URLUtils.percentEncode(tmp.get(key))
);
}
tmp = request.getOauthParameters();
for (String key:tmp.keySet()){
params.put(
URLUtils.percentEncode(key),
URLUtils.percentEncode(tmp.get(key))
);
}
params = MapUtils.sort(params); params = MapUtils.sort(params);
return URLUtils.percentEncode(URLUtils.concatSortedPercentEncodedParams(params)); return URLUtils.percentEncode(URLUtils.concatSortedPercentEncodedParams(params));
} }
@@ -1,28 +0,0 @@
package org.scribe.extractors;
import java.util.regex.*;
import org.scribe.exceptions.*;
import org.scribe.model.*;
import org.scribe.utils.*;
public class JsonTokenExtractor implements AccessTokenExtractor
{
private Pattern accessTokenPattern = Pattern.compile("\"access_token\":\"(\\S*)\"");
@Override
public Token extract(String response)
{
Preconditions.checkEmptyString(response, "Cannot extract a token from a null or empty String");
Matcher matcher = accessTokenPattern.matcher(response);
if(matcher.find())
{
return new Token(matcher.group(1), "");
}
else
{
throw new OAuthException("Cannot extract an acces token. Response was: "+response);
}
}
}
@@ -1,36 +0,0 @@
package org.scribe.extractors;
import java.util.regex.*;
import org.scribe.exceptions.*;
import org.scribe.model.*;
import org.scribe.utils.*;
/**
* Default implementation of {@AccessTokenExtractor}. Conforms to OAuth 2.0
*
*/
public class TokenExtractor20Impl implements AccessTokenExtractor
{
private static final String TOKEN_REGEX = "access_token=(\\S*?)(&(\\S*))?";
private static final String EMPTY_SECRET = "";
/**
* {@inheritDoc}
*/
public Token extract(String response)
{
Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response);
if (matcher.matches())
{
String token = URLUtils.formURLDecode(matcher.group(1));
return new Token(token, EMPTY_SECRET, response);
}
else
{
throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null);
}
}
}
@@ -15,8 +15,7 @@ import org.scribe.utils.*;
*/ */
public class TokenExtractorImpl implements RequestTokenExtractor, AccessTokenExtractor public class TokenExtractorImpl implements RequestTokenExtractor, AccessTokenExtractor
{ {
private static final Pattern TOKEN_REGEX = Pattern.compile("oauth_token=([^&]+)"); private static final String TOKEN_REGEX = "oauth_token=(\\S*)&oauth_token_secret=(\\S*?)(&(.*))?";
private static final Pattern SECRET_REGEX = Pattern.compile("oauth_token_secret=([^&]+)");
/** /**
* {@inheritDoc} * {@inheritDoc}
@@ -24,21 +23,16 @@ public class TokenExtractorImpl implements RequestTokenExtractor, AccessTokenExt
public Token extract(String response) public Token extract(String response)
{ {
Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string"); Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
String token = extract(response, TOKEN_REGEX);
String secret = extract(response, SECRET_REGEX);
return new Token(token, secret, response);
}
private String extract(String response, Pattern p) Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response);
{ if (matcher.matches())
Matcher matcher = p.matcher(response);
if (matcher.find() && matcher.groupCount() >= 1)
{ {
return URLUtils.formURLDecode(matcher.group(1)); String token = URLUtils.urlDecodeWrapper(matcher.group(1));
} String secret = URLUtils.urlDecodeWrapper(matcher.group(2));
else return new Token(token, secret);
} else
{ {
throw new OAuthException("Response body is incorrect. Can't extract token and secret from this: '" + response + "'", null); throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null);
} }
} }
} }
+20 -24
View File
@@ -7,24 +7,20 @@ package org.scribe.model;
*/ */
public class OAuthConfig public class OAuthConfig
{ {
private final String apiKey; private String apiKey;
private final String apiSecret; private String apiSecret;
private final String callback; private String callback;
private final SignatureType signatureType;
private final String scope;
public OAuthConfig(String key, String secret) public OAuthConfig(String key, String secret)
{ {
this(key, secret, null, null, null); this(key,secret,null);
} }
public OAuthConfig(String key, String secret, String callback, SignatureType type, String scope) public OAuthConfig(String key, String secret, String callback)
{ {
this.apiKey = key; this.apiKey = key;
this.apiSecret = secret; this.apiSecret = secret;
this.callback = callback != null ? callback : OAuthConstants.OUT_OF_BAND; this.callback = callback;
this.signatureType = (type != null) ? type : SignatureType.Header;
this.scope = scope;
} }
public String getApiKey() public String getApiKey()
@@ -32,28 +28,28 @@ public class OAuthConfig
return apiKey; return apiKey;
} }
public void setApiKey(String apiKey)
{
this.apiKey = apiKey;
}
public String getApiSecret() public String getApiSecret()
{ {
return apiSecret; return apiSecret;
} }
public void setApiSecret(String apiSecret)
{
this.apiSecret = apiSecret;
}
public String getCallback() public String getCallback()
{ {
return callback; return callback != null ? callback : OAuthConstants.OUT_OF_BAND;
} }
public SignatureType getSignatureType() public void setCallback(String callback)
{ {
return signatureType; this.callback = callback;
}
public String getScope()
{
return scope;
}
public boolean hasScope()
{
return scope != null;
} }
} }
@@ -41,9 +41,4 @@ public class OAuthConstants
//OAuth 2.0 //OAuth 2.0
public static final String ACCESS_TOKEN = "access_token"; public static final String ACCESS_TOKEN = "access_token";
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
public static final String REDIRECT_URI = "redirect_uri";
public static final String CODE = "code";
} }
@@ -1,5 +1,6 @@
package org.scribe.model; package org.scribe.model;
import java.net.MalformedURLException;
import java.util.*; import java.util.*;
/** /**
@@ -19,8 +20,9 @@ public class OAuthRequest extends Request
* *
* @param verb Http verb/method * @param verb Http verb/method
* @param url resource URL * @param url resource URL
* @throws MalformedURLException
*/ */
public OAuthRequest(Verb verb, String url) public OAuthRequest(Verb verb, String url) throws MalformedURLException
{ {
super(verb, url); super(verb, url);
this.oauthParameters = new HashMap<String, String>(); this.oauthParameters = new HashMap<String, String>();
+22 -19
View File
@@ -17,7 +17,7 @@ class Request
{ {
private static final String CONTENT_LENGTH = "Content-Length"; private static final String CONTENT_LENGTH = "Content-Length";
private String url; private URL url;
private Verb verb; private Verb verb;
private Map<String, String> querystringParams; private Map<String, String> querystringParams;
private Map<String, String> bodyParams; private Map<String, String> bodyParams;
@@ -30,11 +30,12 @@ class Request
* *
* @param verb Http Verb (GET, POST, etc) * @param verb Http Verb (GET, POST, etc)
* @param url url with optional querystring parameters. * @param url url with optional querystring parameters.
* @throws MalformedURLException
*/ */
public Request(Verb verb, String url) public Request(Verb verb, String url) throws MalformedURLException
{ {
this.verb = verb; this.verb = verb;
this.url = url; this.url = new URL(url);
this.querystringParams = new HashMap<String, String>(); this.querystringParams = new HashMap<String, String>();
this.bodyParams = new HashMap<String, String>(); this.bodyParams = new HashMap<String, String>();
this.headers = new HashMap<String, String>(); this.headers = new HashMap<String, String>();
@@ -61,10 +62,9 @@ class Request
private void createConnection() throws IOException private void createConnection() throws IOException
{ {
String effectiveUrl = URLUtils.appendParametersToQueryString(url, querystringParams); String effectiveUrl = URLUtils.appendParametersToQueryString(url.toString(), querystringParams);
if (connection == null) if (connection == null)
{ {
System.setProperty("http.keepAlive", "false");
connection = (HttpURLConnection) new URL(effectiveUrl).openConnection(); connection = (HttpURLConnection) new URL(effectiveUrl).openConnection();
} }
} }
@@ -145,22 +145,25 @@ class Request
* Get a {@link Map} of the query string parameters. * Get a {@link Map} of the query string parameters.
* *
* @return a map containing the query string parameters * @return a map containing the query string parameters
* @throws OAuthException if the URL is not valid
*/ */
public Map<String, String> getQueryStringParams() public Map<String, String> getQueryStringParams()
{ {
try
{
Map<String, String> params = new HashMap<String, String>(); Map<String, String> params = new HashMap<String, String>();
String queryString = new URL(url).getQuery(); String query = url.getQuery();
params.putAll(URLUtils.queryStringToMap(queryString)); if (query != null)
params.putAll(this.querystringParams); {
return params; for (String param : query.split("&"))
} {
catch (MalformedURLException mue) String pair[] = param.split("=");
{ String valuePart = "";
throw new OAuthException("Malformed URL", mue); if (pair.length > 1) {
} valuePart = URLUtils.urlDecodeWrapper(pair[1]);
}
params.put(URLUtils.urlDecodeWrapper(pair[0]),valuePart );
}
}
params.putAll(querystringParams);
return params;
} }
/** /**
@@ -180,7 +183,7 @@ class Request
*/ */
public String getUrl() public String getUrl()
{ {
return url; return url.toString();
} }
/** /**
@@ -190,7 +193,7 @@ class Request
*/ */
public String getSanitizedUrl() public String getSanitizedUrl()
{ {
return url.replaceAll("\\?.*", "").replace("\\:\\d{4}", ""); return URLUtils.convertUrlToBaseStringURI(url);
} }
/** /**
@@ -1,7 +0,0 @@
package org.scribe.model;
public enum SignatureType
{
Header,
QueryString
}
-16
View File
@@ -13,7 +13,6 @@ public class Token implements Serializable
private final String token; private final String token;
private final String secret; private final String secret;
private final String rawResponse;
/** /**
* Default constructor * Default constructor
@@ -22,15 +21,9 @@ public class Token implements Serializable
* @param secret token secret * @param secret token secret
*/ */
public Token(String token, String secret) public Token(String token, String secret)
{
this(token, secret, null);
}
public Token(String token, String secret, String rawResponse)
{ {
this.token = token; this.token = token;
this.secret = secret; this.secret = secret;
this.rawResponse = rawResponse;
} }
public String getToken() public String getToken()
@@ -43,15 +36,6 @@ public class Token implements Serializable
return secret; return secret;
} }
public String getRawResponse()
{
if (rawResponse == null)
{
throw new IllegalStateException("This token object was not constructed by scribe and does not have a rawResponse");
}
return rawResponse;
}
@Override @Override
public String toString() public String toString()
{ {
+3 -3
View File
@@ -1,7 +1,5 @@
package org.scribe.model; package org.scribe.model;
import org.scribe.utils.*;
/** /**
* Represents an OAuth verifier code. * Represents an OAuth verifier code.
* *
@@ -19,7 +17,9 @@ public class Verifier
*/ */
public Verifier(String value) public Verifier(String value)
{ {
Preconditions.checkNotNull(value, "Must provide a valid string as verifier"); if (value == null) {
throw new IllegalArgumentException();
}
this.value = value; this.value = value;
} }
@@ -1,8 +1,9 @@
package org.scribe.oauth; package org.scribe.oauth;
import java.util.*; import java.net.MalformedURLException;
import org.scribe.builder.api.*; import org.scribe.builder.api.*;
import org.scribe.exceptions.OAuthException;
import org.scribe.model.*; import org.scribe.model.*;
/** /**
@@ -12,10 +13,12 @@ import org.scribe.model.*;
*/ */
public class OAuth10aServiceImpl implements OAuthService public class OAuth10aServiceImpl implements OAuthService
{ {
private static final String NO_SCOPE = null;
private static final String VERSION = "1.0"; private static final String VERSION = "1.0";
private OAuthConfig config; private OAuthConfig config;
private DefaultApi10a api; private DefaultApi10a api;
private String scope;
/** /**
* Default constructor * Default constructor
@@ -27,6 +30,7 @@ public class OAuth10aServiceImpl implements OAuthService
{ {
this.api = api; this.api = api;
this.config = config; this.config = config;
this.scope = NO_SCOPE;
} }
/** /**
@@ -34,10 +38,14 @@ public class OAuth10aServiceImpl implements OAuthService
*/ */
public Token getRequestToken() public Token getRequestToken()
{ {
OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint()); OAuthRequest request = null;;
request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback()); try {
request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint());
} catch (MalformedURLException e) {
throw new OAuthException("Problems while creating connection", e);
}
addOAuthParams(request, OAuthConstants.EMPTY_TOKEN); addOAuthParams(request, OAuthConstants.EMPTY_TOKEN);
addSignature(request); addOAuthHeader(request);
Response response = request.send(); Response response = request.send();
return api.getRequestTokenExtractor().extract(response.getBody()); return api.getRequestTokenExtractor().extract(response.getBody());
} }
@@ -49,7 +57,8 @@ public class OAuth10aServiceImpl implements OAuthService
request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey()); request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey());
request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod()); request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod());
request.addOAuthParameter(OAuthConstants.VERSION, getVersion()); request.addOAuthParameter(OAuthConstants.VERSION, getVersion());
if(config.hasScope()) request.addOAuthParameter(OAuthConstants.SCOPE, config.getScope()); request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback());
if(scope != NO_SCOPE) request.addOAuthParameter(OAuthConstants.SCOPE, scope);
request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, token)); request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, token));
} }
@@ -58,11 +67,16 @@ public class OAuth10aServiceImpl implements OAuthService
*/ */
public Token getAccessToken(Token requestToken, Verifier verifier) public Token getAccessToken(Token requestToken, Verifier verifier)
{ {
OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); OAuthRequest request = null;
try {
request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
} catch (MalformedURLException e) {
throw new OAuthException("Problems while creating connection", e);
}
request.addOAuthParameter(OAuthConstants.TOKEN, requestToken.getToken()); request.addOAuthParameter(OAuthConstants.TOKEN, requestToken.getToken());
request.addOAuthParameter(OAuthConstants.VERIFIER, verifier.getValue()); request.addOAuthParameter(OAuthConstants.VERIFIER, verifier.getValue());
addOAuthParams(request, requestToken); addOAuthParams(request, requestToken);
addSignature(request); addOAuthHeader(request);
Response response = request.send(); Response response = request.send();
return api.getAccessTokenExtractor().extract(response.getBody()); return api.getAccessTokenExtractor().extract(response.getBody());
} }
@@ -74,7 +88,7 @@ public class OAuth10aServiceImpl implements OAuthService
{ {
request.addOAuthParameter(OAuthConstants.TOKEN, token.getToken()); request.addOAuthParameter(OAuthConstants.TOKEN, token.getToken());
addOAuthParams(request, token); addOAuthParams(request, token);
addSignature(request); addOAuthHeader(request);
} }
/** /**
@@ -85,6 +99,14 @@ public class OAuth10aServiceImpl implements OAuthService
return VERSION; return VERSION;
} }
/**
* {@inheritDoc}
*/
public void addScope(String scope)
{
this.scope = scope;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@@ -99,20 +121,9 @@ public class OAuth10aServiceImpl implements OAuthService
return api.getSignatureService().getSignature(baseString, config.getApiSecret(), token.getSecret()); return api.getSignatureService().getSignature(baseString, config.getApiSecret(), token.getSecret());
} }
private void addSignature(OAuthRequest request) private void addOAuthHeader(OAuthRequest request)
{ {
switch (config.getSignatureType()) String oauthHeader = api.getHeaderExtractor().extract(request);
{ request.addHeader(OAuthConstants.HEADER, oauthHeader);
case Header:
String oauthHeader = api.getHeaderExtractor().extract(request);
request.addHeader(OAuthConstants.HEADER, oauthHeader);
break;
case QueryString:
for (Map.Entry<String, String> entry : request.getOauthParameters().entrySet())
{
request.addQuerystringParameter(entry.getKey(), entry.getValue());
}
break;
}
} }
} }
@@ -22,19 +22,20 @@ public class OAuth20ServiceImpl implements OAuthService
this.config = config; this.config = config;
} }
/**
* {@inheritDoc}
*/
public void addScope(String scope)
{
throw new UnsupportedOperationException("OAuth 2 does not use scopes");
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public Token getAccessToken(Token requestToken, Verifier verifier) public Token getAccessToken(Token requestToken, Verifier verifier)
{ {
OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); throw new UnsupportedOperationException("Unsupported operation, please use 'getAuthorizationUrl' and redirect your users there");
request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue());
request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
if(config.hasScope()) request.addQuerystringParameter(OAuthConstants.SCOPE, config.getScope());
Response response = request.send();
return api.getAccessTokenExtractor().extract(response.getBody());
} }
/** /**
@@ -41,6 +41,13 @@ public interface OAuthService
* @return oauth version as string * @return oauth version as string
*/ */
public String getVersion(); public String getVersion();
/**
* Adds the 'scope' parameter. This is **not** a default OAuth parameter and the setting is optional.
*
* @param scope OAuth Api scope (optional)
*/
public void addScope(String scope);
/** /**
* Returns the URL where you should redirect your users to authenticate * Returns the URL where you should redirect your users to authenticate
@@ -1,40 +0,0 @@
package org.scribe.services;
import org.scribe.exceptions.*;
import org.scribe.utils.*;
/**
* plaintext implementation of {@SignatureService}
*
* @author Pablo Fernandez
*
*/
public class PlaintextSignatureService implements SignatureService
{
private static final String METHOD = "plaintext";
/**
* {@inheritDoc}
*/
public String getSignature(String baseString, String apiSecret, String tokenSecret)
{
try
{
Preconditions.checkEmptyString(apiSecret, "Api secret cant be null or empty string");
return URLUtils.percentEncode(apiSecret) + '&' + URLUtils.percentEncode(tokenSecret);
}
catch (Exception e)
{
throw new OAuthSignatureException(baseString, e);
}
}
/**
* {@inheritDoc}
*/
public String getSignatureMethod()
{
return METHOD;
}
}
@@ -33,19 +33,4 @@ public class MapUtils
Collections.sort(keys); Collections.sort(keys);
return keys; return keys;
} }
/**
* Form-urlDecodes and appends all keys from the source {@link Map} to the
* target {@link Map}
*
* @param source Map from where the keys get copied and decoded
* @param target Map where the decoded keys are copied to
*/
public static void decodeAndAppendEntries(Map<String, String> source, Map<String, String> target)
{
for (String key: source.keySet())
{
target.put(URLUtils.percentEncode(key), URLUtils.percentEncode(source.get(key)));
}
}
} }
+76 -70
View File
@@ -13,9 +13,13 @@ public class URLUtils
{ {
private static final String EMPTY_STRING = ""; private static final String EMPTY_STRING = "";
private static final String UTF_8 = "UTF-8"; private static final String UTF_8 = "UTF-8";
private static final String PAIR_SEPARATOR = "="; private static final char PAIR_SEPARATOR = '=';
private static final String PARAM_SEPARATOR = "&"; private static final char PARAM_SEPARATOR = '&';
private static final char QUERY_STRING_SEPARATOR = '?'; private static final char QUERY_STRING_SEPARATOR = '?';
private static final String HTTP_PROTOCOL = "http";
private static final int HTTP_DEFAULT_PORT = 80;
private static final String HTTPS_PROTOCOL = "https";
private static final int HTTPS_DEFAULT_PORT = 443;
private static final String ERROR_MSG = String.format("Cannot find specified encoding: %s", UTF_8); private static final String ERROR_MSG = String.format("Cannot find specified encoding: %s", UTF_8);
@@ -31,7 +35,7 @@ public class URLUtils
} }
/** /**
* Turns a map into a form-urlencoded string * Turns a map into a form-url-encoded string (key=value&key2&key3=value)
* *
* @param map any map * @param map any map
* @return form-url-encoded string * @return form-url-encoded string
@@ -47,38 +51,49 @@ public class URLUtils
StringBuffer encodedString = new StringBuffer(map.size() * 20); StringBuffer encodedString = new StringBuffer(map.size() * 20);
for (String key : map.keySet()) for (String key : map.keySet())
{ {
encodedString.append(PARAM_SEPARATOR).append(formURLEncode(key)); if(encodedString.length() > 0)
if(map.get(key) != null)
{ {
encodedString.append(PAIR_SEPARATOR).append(formURLEncode(map.get(key))); encodedString.append(PARAM_SEPARATOR);
} }
encodedString.append(urlEncodeWrapper(key));
if (map.get(key).length() > 0) {
encodedString.append(PAIR_SEPARATOR).append(urlEncodeWrapper(map.get(key)));
}
} }
return encodedString.toString().substring(1); return encodedString.toString();
} }
/** /**
* Percent encodes a string * Percent encodes a string
* *
* @param string plain string * @param plain
* @return percent encoded string * @return percent encoded string
*/ */
public static String percentEncode(String string) public static String percentEncode(String string)
{ {
String encoded = formURLEncode(string); Preconditions.checkNotNull(string, "Cannot encode null string");
for (EncodingRule rule : ENCODING_RULES) try
{ {
encoded = rule.apply(encoded); String encoded = URLEncoder.encode(string, UTF_8);
for(EncodingRule rule : ENCODING_RULES)
{
encoded = rule.apply(encoded);
}
return encoded;
}
catch (UnsupportedEncodingException uee)
{
throw new IllegalStateException(ERROR_MSG, uee);
} }
return encoded;
} }
/** /**
* Translates a string into application/x-www-form-urlencoded format * URL encodes a string
* *
* @param plain * @param plain
* @return form-urlencoded string * @return percent encoded string
*/ */
public static String formURLEncode(String string) public static String urlEncodeWrapper(String string)
{ {
Preconditions.checkNotNull(string, "Cannot encode null string"); Preconditions.checkNotNull(string, "Cannot encode null string");
try try
@@ -90,14 +105,14 @@ public class URLUtils
throw new IllegalStateException(ERROR_MSG, uee); throw new IllegalStateException(ERROR_MSG, uee);
} }
} }
/** /**
* Decodes a application/x-www-form-urlencoded string * URL decodes a string
* *
* @param string form-urlencoded string * @param string percent encoded string
* @return plain string * @return plain string
*/ */
public static String formURLDecode(String string) public static String urlDecodeWrapper(String string)
{ {
Preconditions.checkNotNull(string, "Cannot decode null string"); Preconditions.checkNotNull(string, "Cannot decode null string");
try try
@@ -121,57 +136,12 @@ public class URLUtils
{ {
Preconditions.checkNotNull(url, "Cannot append to null URL"); Preconditions.checkNotNull(url, "Cannot append to null URL");
String queryString = URLUtils.formURLEncodeMap(params); String queryString = URLUtils.formURLEncodeMap(params);
if (queryString.equals(EMPTY_STRING)) if (queryString.length() == 0) return url;
{
return url;
}
else
{
url += url.indexOf(QUERY_STRING_SEPARATOR) != -1 ? PARAM_SEPARATOR : QUERY_STRING_SEPARATOR;
url += queryString;
return url;
}
}
/** // Check if there are parameters in the url already and use '&' instead of '?'
* Concats a key-value map into a querystring-like String url += url.indexOf(QUERY_STRING_SEPARATOR) != -1 ? PARAM_SEPARATOR : QUERY_STRING_SEPARATOR;
* url += queryString;
* @param params key-value map return url;
* @return querystring-like String
*/
// TODO Move to MapUtils
public static String concatSortedPercentEncodedParams(Map<String, String> params)
{
StringBuilder result = new StringBuilder();
for (String key : params.keySet())
{
result.append(key).append(PAIR_SEPARATOR);
result.append(params.get(key)).append(PARAM_SEPARATOR);
}
return result.toString().substring(0, result.length() - 1);
}
/**
* Parses and form-urldecodes a querystring-like string into a map
*
* @param queryString querystring-like String
* @return a map with the form-urldecoded parameters
*/
// TODO Move to MapUtils
public static Map<String, String> queryStringToMap(String queryString)
{
Map<String, String> result = new HashMap<String, String>();
if (queryString != null && queryString.length() > 0)
{
for (String param : queryString.split(PARAM_SEPARATOR))
{
String pair[] = param.split(PAIR_SEPARATOR);
String key = formURLDecode(pair[0]);
String value = pair.length > 1 ? formURLDecode(pair[1]) : EMPTY_STRING;
result.put(key, value);
}
}
return result;
} }
private static final class EncodingRule private static final class EncodingRule
@@ -189,4 +159,40 @@ public class URLUtils
return string.replace(ch, toCh); return string.replace(ch, toCh);
} }
} }
public static String concatSortedPercentEncodedParams(Map<String, String> params) {
StringBuilder target = new StringBuilder();
for (String key:params.keySet()){
target.append(key);
target.append(PAIR_SEPARATOR);
target.append(params.get(key));
target.append(PARAM_SEPARATOR);
}
return target.deleteCharAt(target.length() - 1).toString();
}
public static String convertUrlToBaseStringURI(URL url){
URI uri = null;
try {
uri = url.toURI();
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
String scheme = uri.getScheme().toLowerCase();
String host = uri.getHost().toLowerCase();
int port = uri.getPort();
if (
(scheme.equals(HTTP_PROTOCOL) && port == HTTP_DEFAULT_PORT)
|| (scheme.equals(HTTPS_PROTOCOL) && port == HTTPS_DEFAULT_PORT)
){
port = -1;
}
URI baseUri = null;
try {
baseUri = new URI(scheme,null, host, port, uri.getPath(), null, null);
} catch (URISyntaxException e) {
e.printStackTrace();
}
return baseUri.toString();
}
} }
@@ -18,13 +18,12 @@ public class ServiceBuilderTest
} }
@Test @Test
public void shouldReturnConfigDefaultValues() public void shouldReturnOOBasDefaultCallback()
{ {
builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").build(); builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").build();
assertEquals(ApiMock.config.getApiKey(), "key"); assertEquals(ApiMock.config.getApiKey(), "key");
assertEquals(ApiMock.config.getApiSecret(), "secret"); assertEquals(ApiMock.config.getApiSecret(), "secret");
assertEquals(ApiMock.config.getCallback(), OAuthConstants.OUT_OF_BAND); assertEquals(ApiMock.config.getCallback(), OAuthConstants.OUT_OF_BAND);
assertEquals(ApiMock.config.getSignatureType(), SignatureType.Header);
} }
@Test @Test
@@ -36,15 +35,6 @@ public class ServiceBuilderTest
assertEquals(ApiMock.config.getCallback(), "http://example.com"); assertEquals(ApiMock.config.getCallback(), "http://example.com");
} }
@Test
public void shouldAcceptASignatureType()
{
builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").signatureType(SignatureType.QueryString).build();
assertEquals(ApiMock.config.getApiKey(), "key");
assertEquals(ApiMock.config.getApiSecret(), "secret");
assertEquals(ApiMock.config.getSignatureType(), SignatureType.QueryString);
}
@Test(expected=IllegalArgumentException.class) @Test(expected=IllegalArgumentException.class)
public void shouldNotAcceptAnInvalidUrlAsCallback() public void shouldNotAcceptAnInvalidUrlAsCallback()
{ {
@@ -57,17 +47,19 @@ public class ServiceBuilderTest
builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").scope("rss-api").build(); builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").scope("rss-api").build();
assertEquals(ApiMock.config.getApiKey(), "key"); assertEquals(ApiMock.config.getApiKey(), "key");
assertEquals(ApiMock.config.getApiSecret(), "secret"); assertEquals(ApiMock.config.getApiSecret(), "secret");
assertEquals(ApiMock.config.getScope(), "rss-api"); assertEquals(ApiMock.scope, "rss-api");
} }
public static class ApiMock implements Api public static class ApiMock implements Api
{ {
public static OAuthConfig config; public static OAuthConfig config;
public static String scope;
@Override @Override
public OAuthService createService(OAuthConfig config) public OAuthService createService(OAuthConfig config, String scope)
{ {
ApiMock.config = config; ApiMock.config = config;
ApiMock.scope = scope;
return null; return null;
} }
} }
@@ -1,5 +1,6 @@
package org.scribe.examples; package org.scribe.examples;
import java.net.MalformedURLException;
import java.util.*; import java.util.*;
import org.scribe.builder.*; import org.scribe.builder.*;
@@ -11,12 +12,13 @@ public class FacebookExample
{ {
private static final String NETWORK_NAME = "Facebook"; private static final String NETWORK_NAME = "Facebook";
private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/me"; private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/me";
private static final String NO_SECRET_NEEDED = "";
private static final Token EMPTY_TOKEN = null; private static final Token EMPTY_TOKEN = null;
public static void main(String[] args) public static void main(String[] args) throws MalformedURLException
{ {
// Replace these with your own api key and secret // Replace these with your own api key and secret
String apiKey = "your_app_id"; String apiKey = "your_api_key";
String apiSecret = "your_api_secret"; String apiSecret = "your_api_secret";
OAuthService service = new ServiceBuilder() OAuthService service = new ServiceBuilder()
.provider(FacebookApi.class) .provider(FacebookApi.class)
@@ -35,16 +37,9 @@ public class FacebookExample
System.out.println("Got the Authorization URL!"); System.out.println("Got the Authorization URL!");
System.out.println("Now go and authorize Scribe here:"); System.out.println("Now go and authorize Scribe here:");
System.out.println(authorizationUrl); System.out.println(authorizationUrl);
System.out.println("And paste the authorization code here"); System.out.println("And paste the access token here");
System.out.print(">>"); System.out.print(">>");
Verifier verifier = new Verifier(in.nextLine()); Token accessToken = new Token(in.nextLine(), NO_SECRET_NEEDED);
System.out.println();
// Trade the Request Token and Verfier for the Access Token
System.out.println("Trading the Request Token for an Access Token...");
Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
System.out.println("Got the Access Token!");
System.out.println("(if your curious it looks like this: " + accessToken + " )");
System.out.println(); System.out.println();
// Now let's go and ask for a protected resource! // Now let's go and ask for a protected resource!
@@ -1,63 +0,0 @@
package org.scribe.examples;
import java.util.*;
import org.scribe.builder.*;
import org.scribe.builder.api.*;
import org.scribe.model.*;
import org.scribe.oauth.*;
public class Foursquare2Example
{
private static final String PROTECTED_RESOURCE_URL = "https://api.foursquare.com/v2/users/self/friends?oauth_token=";
private static final Token EMPTY_TOKEN = null;
public static void main(String[] args)
{
// Replace these with your own api key and secret
String apiKey = "FEGFXJUFANVVDHVSNUAMUKTTXCP1AJQD53E33XKJ44YP1S4I";
String apiSecret = "AYWKUL5SWPNC0CTQ202QXRUG2NLZYXMRA34ZSDW4AUYBG2RC";
OAuthService service = new ServiceBuilder()
.provider(Foursquare2Api.class)
.apiKey(apiKey)
.apiSecret(apiSecret)
.callback("http://localhost:9000/")
.build();
Scanner in = new Scanner(System.in);
System.out.println("=== Foursquare2's OAuth Workflow ===");
System.out.println();
// Obtain the Authorization URL
System.out.println("Fetching the Authorization URL...");
String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
System.out.println("Got the Authorization URL!");
System.out.println("Now go and authorize Scribe here:");
System.out.println(authorizationUrl);
System.out.println("And paste the authorization code here");
System.out.print(">>");
Verifier verifier = new Verifier(in.nextLine());
System.out.println();
// Trade the Request Token and Verfier for the Access Token
System.out.println("Trading the Request Token for an Access Token...");
Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
System.out.println("Got the Access Token!");
System.out.println("(if your curious it looks like this: " + accessToken + " )");
System.out.println();
// Now let's go and ask for a protected resource!
System.out.println("Now we're going to access a protected resource...");
OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getToken());
service.signRequest(accessToken, request);
Response response = request.send();
System.out.println("Got it! Lets see what we found...");
System.out.println();
System.out.println(response.getCode());
System.out.println(response.getBody());
System.out.println();
System.out.println("Thats it man! Go and build something awesome with Scribe! :)");
}
}
@@ -1,5 +1,6 @@
package org.scribe.examples; package org.scribe.examples;
import java.net.MalformedURLException;
import java.util.Scanner; import java.util.Scanner;
import org.scribe.builder.*; import org.scribe.builder.*;
@@ -11,7 +12,7 @@ public class FoursquareExample
{ {
private static final String PROTECTED_RESOURCE_URL = "http://api.foursquare.com/v1/user"; private static final String PROTECTED_RESOURCE_URL = "http://api.foursquare.com/v1/user";
public static void main(String[] args) public static void main(String[] args) throws MalformedURLException
{ {
OAuthService service = new ServiceBuilder() OAuthService service = new ServiceBuilder()
.provider(FoursquareApi.class) .provider(FoursquareApi.class)
@@ -1,5 +1,6 @@
package org.scribe.examples; package org.scribe.examples;
import java.net.MalformedURLException;
import java.util.*; import java.util.*;
import org.scribe.builder.*; import org.scribe.builder.*;
@@ -14,7 +15,7 @@ public class GoogleExample
private static final String PROTECTED_RESOURCE_URL = "https://docs.google.com/feeds/default/private/full/"; private static final String PROTECTED_RESOURCE_URL = "https://docs.google.com/feeds/default/private/full/";
private static final String SCOPE = "https://docs.google.com/feeds/"; private static final String SCOPE = "https://docs.google.com/feeds/";
public static void main(String[] args) public static void main(String[] args) throws MalformedURLException
{ {
OAuthService service = new ServiceBuilder() OAuthService service = new ServiceBuilder()
.provider(GoogleApi.class) .provider(GoogleApi.class)
@@ -1,5 +1,6 @@
package org.scribe.examples; package org.scribe.examples;
import java.net.MalformedURLException;
import java.util.Scanner; import java.util.Scanner;
import org.scribe.builder.*; import org.scribe.builder.*;
@@ -11,7 +12,7 @@ public class LinkedInExample
{ {
private static final String PROTECTED_RESOURCE_URL = "http://api.linkedin.com/v1/people/~/connections:(id,last-name)"; private static final String PROTECTED_RESOURCE_URL = "http://api.linkedin.com/v1/people/~/connections:(id,last-name)";
public static void main(String[] args) public static void main(String[] args) throws MalformedURLException
{ {
OAuthService service = new ServiceBuilder() OAuthService service = new ServiceBuilder()
.provider(LinkedInApi.class) .provider(LinkedInApi.class)
@@ -1,64 +0,0 @@
package org.scribe.examples;
import java.util.*;
import org.scribe.builder.*;
import org.scribe.builder.api.*;
import org.scribe.model.*;
import org.scribe.oauth.*;
public class LoveFilmExample
{
private static final String NETWORK_NAME = "LoveFilm";
private static final String PROTECTED_RESOURCE_URL = "https://api.lovefilm.com/users";
public static void main(String[] args)
{
// Replace these with your own api key and secret
String apiKey = "your_key";
String apiSecret = "your_secret";
OAuthService service = new ServiceBuilder().provider(LoveFilmApi.class).apiKey(apiKey).apiSecret(apiSecret).build();
Scanner in = new Scanner(System.in);
System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
System.out.println();
// Grab a request token.
System.out.println("Fetching request token.");
Token requestToken = service.getRequestToken();
System.out.println("Got it ... ");
System.out.println(requestToken.getToken());
// Obtain the Authorization URL
System.out.println("Fetching the Authorization URL...");
String authorizationUrl = service.getAuthorizationUrl(requestToken);
System.out.println("Got the Authorization URL!");
System.out.println("Now go and authorize Scribe here:");
System.out.println(authorizationUrl);
System.out.println("And paste the authorization code here");
System.out.print(">>");
Verifier verifier = new Verifier(in.nextLine());
System.out.println();
// Trade the Request Token and Verfier for the Access Token
System.out.println("Trading the Request Token for an Access Token...");
Token accessToken = service.getAccessToken(requestToken, verifier);
System.out.println("Got the Access Token!");
System.out.println("(if your curious it looks like this: " + accessToken + " )");
System.out.println();
// Now let's go and ask for a protected resource!
System.out.println("Now we're going to access a protected resource...");
OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL);
service.signRequest(accessToken, request);
Response response = request.send();
System.out.println("Got it! Lets see what we found...");
System.out.println();
System.out.println(response.getCode());
System.out.println(response.getBody());
System.out.println();
System.out.println("Thats it man! Go and build something awesome with Scribe! :)");
}
}
@@ -1,5 +1,6 @@
package org.scribe.examples; package org.scribe.examples;
import java.net.MalformedURLException;
import java.util.Scanner; import java.util.Scanner;
import org.scribe.builder.*; import org.scribe.builder.*;
@@ -11,7 +12,7 @@ public class TwitterExample
{ {
private static final String PROTECTED_RESOURCE_URL = "http://api.twitter.com/1/account/verify_credentials.xml"; private static final String PROTECTED_RESOURCE_URL = "http://api.twitter.com/1/account/verify_credentials.xml";
public static void main(String[] args) public static void main(String[] args) throws MalformedURLException
{ {
OAuthService service = new ServiceBuilder() OAuthService service = new ServiceBuilder()
.provider(TwitterApi.class) .provider(TwitterApi.class)
@@ -1,5 +1,6 @@
package org.scribe.examples; package org.scribe.examples;
import java.net.MalformedURLException;
import java.util.Scanner; import java.util.Scanner;
import org.scribe.builder.*; import org.scribe.builder.*;
@@ -11,7 +12,7 @@ public class YahooExample
{ {
private static final String PROTECTED_RESOURCE_URL = "http://social.yahooapis.com/v1/user/A6ROU63MXWDCW3Y5MGCYWVHDJI/profile/status?format=json"; private static final String PROTECTED_RESOURCE_URL = "http://social.yahooapis.com/v1/user/A6ROU63MXWDCW3Y5MGCYWVHDJI/profile/status?format=json";
public static void main(String[] args) public static void main(String[] args) throws MalformedURLException
{ {
OAuthService service = new ServiceBuilder() OAuthService service = new ServiceBuilder()
.provider(YahooApi.class) .provider(YahooApi.class)
@@ -2,6 +2,8 @@ package org.scribe.extractors;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.net.MalformedURLException;
import org.junit.*; import org.junit.*;
import org.scribe.exceptions.*; import org.scribe.exceptions.*;
import org.scribe.model.*; import org.scribe.model.*;
@@ -12,12 +14,16 @@ public class BaseStringExtractorTest
private BaseStringExtractorImpl extractor; private BaseStringExtractorImpl extractor;
private OAuthRequest request; private OAuthRequest request;
private OAuthRequest request2;
@Before @Before
public void setup() public void setup() throws MalformedURLException
{ {
request = ObjectMother.createSampleOAuthRequest(); request = ObjectMother.createSampleOAuthRequest();
request2 = ObjectMother.createSampleOAuthRequest2();
extractor = new BaseStringExtractorImpl(); extractor = new BaseStringExtractorImpl();
} }
@Test @Test
@@ -27,6 +33,14 @@ public class BaseStringExtractorTest
String baseString = extractor.extract(request); String baseString = extractor.extract(request);
assertEquals(expected, baseString); assertEquals(expected, baseString);
} }
@Test
public void shouldExtractBaseStringFromOAuthRequest2()
{
String expected = "GET&http%3A%2F%2Fexample.com&oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456";
String baseString = extractor.extract(request2);
assertEquals(expected, baseString);
}
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfRquestIsNull() public void shouldThrowExceptionIfRquestIsNull()
@@ -36,7 +50,7 @@ public class BaseStringExtractorTest
} }
@Test(expected = OAuthParametersMissingException.class) @Test(expected = OAuthParametersMissingException.class)
public void shouldThrowExceptionIfRquestHasNoOAuthParameters() public void shouldThrowExceptionIfRquestHasNoOAuthParameters() throws MalformedURLException
{ {
OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com"); OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com");
extractor.extract(request); extractor.extract(request);
@@ -2,6 +2,8 @@ package org.scribe.extractors;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.net.MalformedURLException;
import org.junit.*; import org.junit.*;
import org.scribe.exceptions.*; import org.scribe.exceptions.*;
import org.scribe.model.*; import org.scribe.model.*;
@@ -14,7 +16,7 @@ public class HeaderExtractorTest
private OAuthRequest request; private OAuthRequest request;
@Before @Before
public void setup() public void setup() throws MalformedURLException
{ {
request = ObjectMother.createSampleOAuthRequest(); request = ObjectMother.createSampleOAuthRequest();
extractor = new HeaderExtractorImpl(); extractor = new HeaderExtractorImpl();
@@ -37,7 +39,7 @@ public class HeaderExtractorTest
} }
@Test(expected = OAuthParametersMissingException.class) @Test(expected = OAuthParametersMissingException.class)
public void shouldExceptionIfRequestHasNoOAuthParams() public void shouldExceptionIfRequestHasNoOAuthParams() throws MalformedURLException
{ {
OAuthRequest emptyRequest = new OAuthRequest(Verb.GET, "http://example.com"); OAuthRequest emptyRequest = new OAuthRequest(Verb.GET, "http://example.com");
extractor.extract(emptyRequest); extractor.extract(emptyRequest);
@@ -1,31 +0,0 @@
package org.scribe.extractors;
import static org.junit.Assert.*;
import org.junit.*;
import org.scribe.model.*;
public class JsonTokenExtractorTest
{
private String response = "'{ \"access_token\":\"I0122HHJKLEM21F3WLPYHDKGKZULAUO4SGMV3ABKFTDT3T3X\"}'";
private JsonTokenExtractor extractor = new JsonTokenExtractor();
@Test
public void shouldParseResponse()
{
Token token = extractor.extract(response);
assertEquals(token.getToken(), "I0122HHJKLEM21F3WLPYHDKGKZULAUO4SGMV3ABKFTDT3T3X");
}
@Test(expected=IllegalArgumentException.class)
public void shouldThrowExceptionIfForNullParameters()
{
extractor.extract(null);
}
@Test(expected=IllegalArgumentException.class)
public void shouldThrowExceptionIfForEmptyStrings()
{
extractor.extract("");
}
}
@@ -1,58 +0,0 @@
package org.scribe.extractors;
import static org.junit.Assert.*;
import org.junit.*;
import org.scribe.exceptions.*;
import org.scribe.model.*;
public class TokenExtractor20Test
{
private TokenExtractor20Impl extractor;
@Before
public void setup()
{
extractor = new TokenExtractor20Impl();
}
@Test
public void shouldExtractTokenFromOAuthStandardResponse()
{
String response = "access_token=166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE";
Token extracted = extractor.extract(response);
assertEquals("166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE", extracted.getToken());
assertEquals("", extracted.getSecret());
}
@Test
public void shouldExtractTokenFromResponseWithExpiresParam()
{
String response = "access_token=166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE&expires=5108";
Token extracted = extractor.extract(response);
assertEquals("166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE", extracted.getToken());
assertEquals("", extracted.getSecret());
}
@Test(expected = OAuthException.class)
public void shouldThrowExceptionIfTokenIsAbsent()
{
String response = "&expires=5108";
extractor.extract(response);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfResponseIsNull()
{
String response = null;
extractor.extract(response);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfResponseIsEmptyString()
{
String response = "";
extractor.extract(response);
}
}
@@ -26,15 +26,6 @@ public class TokenExtractorTest
assertEquals("hdhd0244k9j7ao03", extracted.getSecret()); assertEquals("hdhd0244k9j7ao03", extracted.getSecret());
} }
@Test
public void shouldExtractTokenFromInvertedOAuthStandardResponse()
{
String response = "oauth_token_secret=hh5s93j4hdidpola&oauth_token=hdhd0244k9j7ao03";
Token extracted = extractor.extract(response);
assertEquals("hh5s93j4hdidpola", extracted.getSecret());
assertEquals("hdhd0244k9j7ao03", extracted.getToken());
}
@Test @Test
public void shouldExtractTokenFromResponseWithCallbackConfirmed() public void shouldExtractTokenFromResponseWithCallbackConfirmed()
{ {
@@ -12,14 +12,12 @@ public class OAuthConfigTest
{ {
OAuthConfig config = new OAuthConfig("key", "secret"); OAuthConfig config = new OAuthConfig("key", "secret");
assertEquals(OAuthConstants.OUT_OF_BAND, config.getCallback()); assertEquals(OAuthConstants.OUT_OF_BAND, config.getCallback());
assertEquals(SignatureType.Header, config.getSignatureType());
assertFalse(config.hasScope());
} }
@Test @Test
public void shouldOverrideDefaultsIfSet() public void shouldOverrideDefaultsIfSet()
{ {
OAuthConfig config = new OAuthConfig("key", "secret", "http://callback", SignatureType.Header, "scope"); OAuthConfig config = new OAuthConfig("key", "secret", "http://callback");
assertEquals("http://callback", config.getCallback()); assertEquals("http://callback", config.getCallback());
assertEquals("key", config.getApiKey()); assertEquals("key", config.getApiKey());
assertEquals("secret", config.getApiSecret()); assertEquals("secret", config.getApiSecret());
@@ -2,6 +2,8 @@ package org.scribe.model;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.net.MalformedURLException;
import org.junit.*; import org.junit.*;
public class OAuthRequestTest public class OAuthRequestTest
@@ -10,7 +12,7 @@ public class OAuthRequestTest
private OAuthRequest request; private OAuthRequest request;
@Before @Before
public void setup() public void setup() throws MalformedURLException
{ {
request = new OAuthRequest(Verb.GET, "http://example.com"); request = new OAuthRequest(Verb.GET, "http://example.com");
} }
@@ -2,6 +2,8 @@ package org.scribe.model;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.net.MalformedURLException;
import org.junit.*; import org.junit.*;
public class RequestTest public class RequestTest
@@ -16,8 +18,6 @@ public class RequestTest
{ {
connection = new ConnectionStub(); connection = new ConnectionStub();
postRequest = new Request(Verb.POST, "http://example.com"); postRequest = new Request(Verb.POST, "http://example.com");
postRequest.addBodyParameter("param", "value");
postRequest.addBodyParameter("param with spaces", "value with spaces");
postRequest.setConnection(connection); postRequest.setConnection(connection);
getRequest = new Request(Verb.GET, "http://example.com?qsparam=value&other+param=value+with+spaces"); getRequest = new Request(Verb.GET, "http://example.com?qsparam=value&other+param=value+with+spaces");
getRequest.setConnection(connection); getRequest.setConnection(connection);
@@ -37,6 +37,7 @@ public class RequestTest
assertEquals(0, postRequest.getQueryStringParams().size()); assertEquals(0, postRequest.getQueryStringParams().size());
assertTrue(getRequest.getQueryStringParams().containsKey("qsparam")); assertTrue(getRequest.getQueryStringParams().containsKey("qsparam"));
assertTrue(getRequest.getQueryStringParams().get("qsparam").equals("value")); assertTrue(getRequest.getQueryStringParams().get("qsparam").equals("value"));
assertTrue(getRequest.getQueryStringParams().get("other param").equals("value with spaces"));
} }
@Test @Test
@@ -50,10 +51,12 @@ public class RequestTest
} }
@Test @Test
public void shouldSetBodyParamsAndAddContentLength() public void shouldSetBodyParamsAndHeaders()
{ {
assertEquals("param=value&param+with+spaces=value+with+spaces", postRequest.getBodyContents()); postRequest.addBodyParameter("param", "value");
postRequest.addBodyParameter("param two", "value with spaces");
postRequest.send(); postRequest.send();
assertEquals("param+two=value+with+spaces&param=value", postRequest.getBodyContents());
assertTrue(connection.getHeaders().containsKey("Content-Length")); assertTrue(connection.getHeaders().containsKey("Content-Length"));
} }
@@ -67,7 +70,7 @@ public class RequestTest
} }
@Test @Test
public void shouldAllowAddingQuerystringParametersAfterCreation() public void shouldAllowAddingQuerystringParametersAfterCreation() throws MalformedURLException
{ {
Request request = new Request(Verb.GET, "http://example.com?one=val"); Request request = new Request(Verb.GET, "http://example.com?one=val");
request.addQuerystringParameter("two", "other val"); request.addQuerystringParameter("two", "other val");
@@ -76,8 +79,36 @@ public class RequestTest
} }
@Test @Test
public void shouldHandleQueryStringSpaceEncodingProperly() public void sanatizeUrlTest() throws MalformedURLException
{ {
assertTrue(getRequest.getQueryStringParams().get("other param").equals("value with spaces")); Request request = new Request(Verb.GET, "http://example.com?one=val");
assertEquals("http://example.com", request.getSanitizedUrl());
request = new Request(Verb.GET, "http://EXAMPLE.com:80/?one=val");
assertEquals("http://example.com/", request.getSanitizedUrl());
request = new Request(Verb.GET, "http://EXAMPLE.com:8080?one=val");
assertEquals("http://example.com:8080", request.getSanitizedUrl());
request = new Request(Verb.GET, "http://EXAMPLE.com:8080?one=val");
assertEquals("http://example.com:8080", request.getSanitizedUrl());
request = new Request(Verb.GET, "http://EXAMPLE.com:80/test/?one=val");
assertEquals("http://example.com/test/", request.getSanitizedUrl());
request = new Request(Verb.GET, "http://EXAMPLE.com:8080/test/?one=val#Hello");
assertEquals("http://example.com:8080/test/", request.getSanitizedUrl());
request = new Request(Verb.GET, "HTTP://EXAMPLE.com:8080/test/?one=val#Hello");
assertEquals("http://example.com:8080/test/", request.getSanitizedUrl());
//From RFC5849 example p.20
request = new Request(Verb.GET, "http://example.com:80/r%20v/X?id=123");
assertEquals("http://example.com/r%20v/X", request.getSanitizedUrl());
//From RFC5849 example p.20
request = new Request(Verb.GET, "https://www.example.com:8080/?q=1");
assertEquals("https://www.example.com:8080/", request.getSanitizedUrl());
} }
} }
@@ -0,0 +1,14 @@
package org.scribe.model;
import org.junit.*;
public class VerifierTest
{
@Test(expected = IllegalArgumentException.class)
public void shouldThrowErrorForNullString()
{
new Verifier(null);
}
}
@@ -1,11 +1,13 @@
package org.scribe.test.helpers; package org.scribe.test.helpers;
import java.net.MalformedURLException;
import org.scribe.model.*; import org.scribe.model.*;
public class ObjectMother public class ObjectMother
{ {
public static OAuthRequest createSampleOAuthRequest() public static OAuthRequest createSampleOAuthRequest() throws MalformedURLException
{ {
OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com"); OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com");
request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456");
@@ -14,4 +16,14 @@ public class ObjectMother
request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature"); request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature");
return request; return request;
} }
public static OAuthRequest createSampleOAuthRequest2() throws MalformedURLException
{
OAuthRequest request = new OAuthRequest(Verb.GET, "http://EXAMPLE.com");
request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456");
request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&");
request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback");
request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature");
return request;
}
} }
@@ -28,17 +28,6 @@ public class URLUtilsTest
assertEquals(expected, URLUtils.formURLEncodeMap(params)); assertEquals(expected, URLUtils.formURLEncodeMap(params));
} }
@Test
public void shouldFormURLEncodeMapWithMissingValues()
{
Map<String, String> params = new LinkedHashMap<String, String>();
params.put("key", "value");
params.put("key with spaces", null);
String expected = "key=value&key+with+spaces";
assertEquals(expected, URLUtils.formURLEncodeMap(params));
}
@Test @Test
public void shouldPercentEncodeString() public void shouldPercentEncodeString()
{ {
@@ -48,32 +37,24 @@ public class URLUtilsTest
} }
@Test @Test
public void shouldFormURLEncodeString() public void shouldPercentDecodeString()
{
String toEncode = "this is a test &^";
String expected = "this+is+a+test+%26%5E";
assertEquals(expected, URLUtils.formURLEncode(toEncode));
}
@Test
public void shouldFormURLDecodeString()
{ {
String toDecode = "this+is+a+test+%26%5E"; String toDecode = "this+is+a+test+%26%5E";
String expected = "this is a test &^"; String expected = "this is a test &^";
assertEquals(expected, URLUtils.formURLDecode(toDecode)); assertEquals(expected, URLUtils.urlDecodeWrapper(toDecode));
} }
@Test @Test
public void shouldPercentEncodeAllSpecialCharacters() public void shouldEncodeAllSpecialCharacters()
{ {
String plain = "!*'();:@&=+$,/?#[]"; String plain = "!*'();:@&=+$,/?#[]";
String encoded = "%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D"; String encoded = "%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D";
assertEquals(encoded, URLUtils.percentEncode(plain)); assertEquals(encoded, URLUtils.percentEncode(plain));
assertEquals(plain, URLUtils.formURLDecode(encoded)); assertEquals(plain, URLUtils.urlDecodeWrapper(encoded));
} }
@Test @Test
public void shouldNotPercentEncodeReservedCharacters() public void shouldNotEncodeReservedCharacters()
{ {
String plain = "abcde123456-._~"; String plain = "abcde123456-._~";
String encoded = plain; String encoded = plain;
@@ -98,7 +79,7 @@ public class URLUtilsTest
public void shouldThrowExceptionIfStringToDecodeIsNull() public void shouldThrowExceptionIfStringToDecodeIsNull()
{ {
String toDecode = null; String toDecode = null;
URLUtils.formURLDecode(toDecode); URLUtils.urlDecodeWrapper(toDecode);
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@@ -147,7 +128,7 @@ public class URLUtilsTest
} }
@Test @Test
public void shouldPercentEncodePlusSymbol() public void shouldEncodePlusSymbol()
{ {
String plain = "7aEP+jNAwvjc0mjhqg0nuXPf"; String plain = "7aEP+jNAwvjc0mjhqg0nuXPf";
String encoded = "7aEP%2BjNAwvjc0mjhqg0nuXPf"; String encoded = "7aEP%2BjNAwvjc0mjhqg0nuXPf";
@@ -156,11 +137,11 @@ public class URLUtilsTest
} }
@Test @Test
public void shouldURLDecodePlusSymbol() public void shouldDecodePlusSymbol()
{ {
String encoded = "oauth_verifier=7aEP%2BjNAwvjc0mjhqg0nuXPf"; String encoded = "oauth_verifier=7aEP%2BjNAwvjc0mjhqg0nuXPf";
String expected = "oauth_verifier=7aEP+jNAwvjc0mjhqg0nuXPf"; String expected = "oauth_verifier=7aEP+jNAwvjc0mjhqg0nuXPf";
Assert.assertEquals(expected, URLUtils.formURLDecode(encoded)); Assert.assertEquals(expected, URLUtils.urlDecodeWrapper(encoded));
} }
} }