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
78 changed files with 756 additions and 2185 deletions

No files matched your search

-5
View File
@@ -5,11 +5,6 @@
.project
.settings
# IntelliJ Idea settings
.idea
scribe.iml
# Binaries
target
+4 -12
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!
h1. Why use Scribe?
@@ -18,12 +20,10 @@ h3. Threadsafe
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
* Facebook
* Yahoo
* LinkedIn
@@ -38,8 +38,6 @@ h3. Supports all major 1.0a and 2.0 OAuth APIs out-of-the-box
* Yammer
* Windows Live
* and many more! check the "examples folder":http://github.com/fernandezpablo85/scribe-java/tree/master/src/test/java/org/scribe/examples
h3. Small and modular
@@ -63,7 +61,7 @@ You can pull scribe from a maven repository, just add this to your __pom.xml__ f
@<dependency>@
@<groupId>org.scribe</groupId>@
@<artifactId>scribe</artifactId>@
@<version>1.3.0</version>@
@<version>1.0.6</version>@
@</dependency>@
h1. Getting started in less than 2 minutes
@@ -72,12 +70,6 @@ Check the "Getting Started":http://wiki.github.com/fernandezpablo85/scribe-java/
h1. Please Read the "FAQ":http://wiki.github.com/fernandezpablo85/scribe-java/faq before creating an issue :)
h1. Questions?
Feel free to drop me an email, but there's already a "StackOvferflow":http://stackoverflow.com tag for "scribe":http://stackoverflow.com/questions/tagged/scribe you should use. I'm subscribed to it so I'll pick the question immediately.
Note that it really helps to run scribe on **debug** mode (since 1.3.0), to get additional info. To do this simply call the @.debug()@ method on the @ServiceBuilder@.
h1. About me
"LinkedIn profile":http://www.linkedin.com/in/fernandezpablo85
-2
View File
@@ -1,2 +0,0 @@
#!/bin/sh
mvn source:jar javadoc:jar package gpg:sign repository:bundle-create -Dgpg.passphrase=$1
+1 -43
View File
@@ -28,46 +28,4 @@
[1.1.1]
* 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)
* 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.2.1]
* FEATURE: Added custom charset support to Request (thanks Eric Genet)
* FEATURE: Added support for Vkontakte (thanks dotbg)
* FEATURE: Added Sohu Weibo, Netease Weibo & Sina Weibo Apis (thanks Arthur Wang)
* FEATURE: Added support for persistent Http Connections (thanks Craig Minton)
[1.2.2]
* FIX: Added support for JDK 1.5. Issue #146 (thanks Sripathi Krishnan)
* FIX: Invalid character constant error message. Issue #137 (thanks Scott Scoble)
* FEATURE: Added a Api class to handle windows live authentication. Issue #135 (thanks Tomas Lin)
* FEATURE: Added refresh token feature for Yahoo! API. Issue #134 (thanks Aaron Foltz)
* FEATURE: Added support for Plurk API. Issue #130 (thanks Chia-Wei Li)
* FIX: Request.setConnectTimeout() and setReadTimeout() throw NPE. Issue #123 (thanks thepizzle)
[1.2.3]
* FEATURE: Added default Content-Type header
* FEATURE: Sapo Api
* FEATURE: Plurk Mobile Api
* FEATURE: Kaixin and QWeibo Apis
* FEATURE: SimpleGeo Api
* FEATURE: Overloaded provider() method to support instances as well as classes (thanks dustismo)
+3 -3
View File
@@ -4,7 +4,7 @@
<groupId>org.scribe</groupId>
<artifactId>scribe</artifactId>
<packaging>jar</packaging>
<version>1.3.0</version>
<version>1.1.0</version>
<name>Scribe OAuth Library</name>
<description>The best OAuth library out there</description>
<url>http://github.com/fernandezpablo85/scribe-java</url>
@@ -63,8 +63,8 @@
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
@@ -1,6 +1,5 @@
package org.scribe.builder;
import java.io.*;
import org.scribe.builder.api.*;
import org.scribe.exceptions.*;
import org.scribe.model.*;
@@ -21,8 +20,6 @@ public class ServiceBuilder
private String callback;
private Api api;
private String scope;
private SignatureType signatureType;
private OutputStream debugStream;
/**
* Default constructor
@@ -30,8 +27,6 @@ public class ServiceBuilder
public ServiceBuilder()
{
this.callback = OAuthConstants.OUT_OF_BAND;
this.signatureType = SignatureType.Header;
this.debugStream = null;
}
/**
@@ -127,32 +122,6 @@ public class ServiceBuilder
this.scope = scope;
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;
}
public ServiceBuilder debugStream(OutputStream stream)
{
Preconditions.checkNotNull(stream, "debug stream can't be null");
this.debugStream = stream;
return this;
}
public ServiceBuilder debug()
{
this.debugStream(System.out);
return this;
}
/**
* Returns the fully configured {@link OAuthService}
@@ -164,6 +133,6 @@ public class ServiceBuilder
Preconditions.checkNotNull(api, "You must specify a valid api through the provider() method");
Preconditions.checkEmptyString(apiKey, "You must provide an api key");
Preconditions.checkEmptyString(apiSecret, "You must provide an api secret");
return api.createService(new OAuthConfig(apiKey, apiSecret, callback, signatureType, scope, debugStream));
return api.createService(new OAuthConfig(apiKey, apiSecret, callback), scope);
}
}
@@ -21,5 +21,5 @@ public interface Api
*
* @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 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);
}
@@ -1,6 +1,5 @@
package org.scribe.builder.api;
import org.scribe.extractors.*;
import org.scribe.model.*;
import org.scribe.oauth.*;
@@ -23,33 +22,6 @@ import org.scribe.oauth.*;
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
* your application.
@@ -62,7 +34,7 @@ public abstract class DefaultApi20 implements Api
/**
* {@inheritDoc}
*/
public OAuthService createService(OAuthConfig config)
public OAuthService createService(OAuthConfig config, String scope)
{
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,33 +1,16 @@
package org.scribe.builder.api;
import org.scribe.model.*;
import org.scribe.utils.*;
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 SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s";
@Override
public String getAccessTokenEndpoint()
{
return "https://graph.facebook.com/oauth/access_token";
}
private static final String AUTHORIZE_URL = "https://graph.facebook.com/oauth/authorize?response_type=token&client_id=%s&redirect_uri=%s";
@Override
public String getAuthorizationUrl(OAuthConfig config)
{
Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Facebook does not support OOB");
// Append scope if present
if(config.hasScope())
{
return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope()));
}
else
{
return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()));
}
return String.format(AUTHORIZE_URL, config.getApiKey(), URLUtils.urlEncodeWrapper(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(), OAuthEncoder.encode(config.getCallback()));
}
@Override
public AccessTokenExtractor getAccessTokenExtractor()
{
return new JsonTokenExtractor();
}
}
@@ -1,40 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.*;
public class KaixinApi extends DefaultApi10a
{
private static final String REQUEST_TOKEN_URL = "http://api.kaixin001.com/oauth/request_token";
private static final String ACCESS_TOKEN_URL = "http://api.kaixin001.com/oauth/access_token";
private static final String AUTHORIZE_URL = "http://api.kaixin001.com/oauth/authorize?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());
}
@Override
public Verb getRequestTokenVerb()
{
return Verb.GET;
}
@Override
public Verb getAccessTokenVerb()
{
return Verb.GET;
}
}
@@ -1,40 +0,0 @@
package org.scribe.builder.api;
import org.scribe.extractors.*;
import org.scribe.model.*;
import org.scribe.utils.*;
public class LiveApi extends DefaultApi20
{
private static final String AUTHORIZE_URL = "https://oauth.live.com/authorize?client_id=%s&redirect_uri=%s&response_type=code";
private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s";
@Override
public String getAccessTokenEndpoint()
{
return "https://oauth.live.com/token?grant_type=authorization_code";
}
@Override
public String getAuthorizationUrl(OAuthConfig config)
{
Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Live does not support OOB");
// Append scope if present
if (config.hasScope())
{
return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope()));
}
else
{
return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(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());
}
}
@@ -1,47 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.*;
public class NeteaseWeibooApi extends DefaultApi10a
{
private static final String REQUEST_TOKEN_URL = "http://api.t.163.com/oauth/request_token";
private static final String ACCESS_TOKEN_URL = "http://api.t.163.com/oauth/access_token";
private static final String AUTHORIZE_URL = "http://api.t.163.com/oauth/authorize?oauth_token=%s";
private static final String AUTHENTICATE_URL = "http://api.t.163.com/oauth/authenticate?oauth_token=%s";
@Override
public String getRequestTokenEndpoint()
{
return REQUEST_TOKEN_URL;
}
@Override
public String getAccessTokenEndpoint()
{
return ACCESS_TOKEN_URL;
}
@Override
/**
* this method will ignore your callback
* if you're creating a desktop client please choose this url
* else your can call getAuthenticateUrl
*
* via http://open.t.163.com/wiki/index.php?title=%E8%AF%B7%E6%B1%82%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83Token(oauth/authorize)
*/
public String getAuthorizationUrl(Token requestToken)
{
return String.format(AUTHORIZE_URL, requestToken.getToken());
}
/**
* this method is for web client with callback url
* if you're creating a desktop client please call getAuthorizationUrl
*
* via http://open.t.163.com/wiki/index.php?title=%E8%AF%B7%E6%B1%82%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83Token(oauth/authenticate)
*/
public String getAuthenticateUrl(Token requestToken)
{
return String.format(AUTHENTICATE_URL, requestToken.getToken());
}
}
@@ -1,39 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.Token;
public class PlurkApi extends DefaultApi10a
{
private static final String REQUEST_TOKEN_URL = "http://www.plurk.com/OAuth/request_token";
private static final String AUTHORIZATION_URL = "http://www.plurk.com/OAuth/authorize?oauth_token=%s";
private static final String ACCESS_TOKEN_URL = "http://www.plurk.com/OAuth/access_token";
@Override
public String getRequestTokenEndpoint()
{
return REQUEST_TOKEN_URL;
}
@Override
public String getAuthorizationUrl(Token requestToken)
{
return String.format(AUTHORIZATION_URL, requestToken.getToken());
}
@Override
public String getAccessTokenEndpoint()
{
return ACCESS_TOKEN_URL;
}
public class Mobile extends PlurkApi
{
private static final String AUTHORIZATION_URL = "http://www.plurk.com/m/authorize?oauth_token=%s";
@Override
public String getAuthorizationUrl(Token requestToken)
{
return String.format(AUTHORIZATION_URL, requestToken.getToken());
}
}
}
@@ -1,28 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.*;
public class QWeiboApi extends DefaultApi10a
{
private static final String REQUEST_TOKEN_URL = "https://open.t.qq.com/cgi-bin/request_token";
private static final String ACCESS_TOKEN_URL = "https://open.t.qq.com/cgi-bin/access_token";
private static final String AUTHORIZE_URL = "https://open.t.qq.com/cgi-bin/authorize?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());
}
}
@@ -1,40 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.*;
public class SapoApi extends DefaultApi10a
{
private static final String AUTHORIZE_URL = "https://id.sapo.pt/oauth/authorize?oauth_token=%s";
private static final String ACCESS_URL = "https://id.sapo.pt/oauth/access_token";
private static final String REQUEST_URL = "https://id.sapo.pt/oauth/request_token";
@Override
public String getAccessTokenEndpoint()
{
return ACCESS_URL;
}
@Override
public String getRequestTokenEndpoint()
{
return REQUEST_URL;
}
@Override
public String getAuthorizationUrl(Token requestToken)
{
return String.format(AUTHORIZE_URL, requestToken.getToken());
}
@Override
public Verb getRequestTokenVerb()
{
return Verb.GET;
}
@Override
public Verb getAccessTokenVerb()
{
return Verb.GET;
}
}
@@ -1,29 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.Token;
/**
* @author: Pablo Fernandez
*/
public class SimpleGeoApi extends DefaultApi10a
{
private static final String ENDPOINT = "these are not used since SimpleGeo uses 2 legged OAuth";
@Override
public String getRequestTokenEndpoint()
{
return ENDPOINT;
}
@Override
public String getAccessTokenEndpoint()
{
return ENDPOINT;
}
@Override
public String getAuthorizationUrl(Token requestToken)
{
return ENDPOINT;
}
}
@@ -1,28 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.*;
public class SinaWeiboApi extends DefaultApi10a
{
private static final String REQUEST_TOKEN_URL = "http://api.t.sina.com.cn/oauth/request_token";
private static final String ACCESS_TOKEN_URL = "http://api.t.sina.com.cn/oauth/access_token";
private static final String AUTHORIZE_URL = "http://api.t.sina.com.cn/oauth/authorize?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());
}
}
@@ -1,28 +0,0 @@
package org.scribe.builder.api;
import org.scribe.model.*;
public class SohuWeiboApi extends DefaultApi10a
{
private static final String REQUEST_TOKEN_URL = "http://api.t.sohu.com/oauth/request_token";
private static final String ACCESS_TOKEN_URL = "http://api.t.sohu.com/oauth/access_token";
private static final String AUTHORIZE_URL = "http://api.t.sohu.com/oauth/authorize?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,62 +5,22 @@ import org.scribe.model.Token;
public class TwitterApi extends DefaultApi10a
{
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
public String getAccessTokenEndpoint()
{
return "http://" + ACCESS_TOKEN_RESOURCE;
return "http://api.twitter.com/oauth/access_token";
}
@Override
public String getRequestTokenEndpoint()
{
return "http://" + REQUEST_TOKEN_RESOURCE;
return "http://api.twitter.com/oauth/request_token";
}
@Override
public String getAuthorizationUrl(Token requestToken)
{
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;
}
}
/**
* Twitter 'friendlier' authorization endpoint for OAuth.
*
* Uses SSL.
*/
public static class Authenticate extends SSL
{
private static final String AUTHENTICATE_URL = "https://api.twitter.com/oauth/authenticate?oauth_token=%s";
@Override
public String getAuthorizationUrl(Token requestToken)
{
return String.format(AUTHENTICATE_URL, requestToken.getToken());
}
}
/**
* Just an alias to the default (SSL) authorization endpoint.
*
* Need to include this for symmetry with 'Authenticate' only.
*/
public static class Authorize extends SSL{}
}
@@ -1,41 +0,0 @@
package org.scribe.builder.api;
import org.scribe.extractors.*;
import org.scribe.utils.*;
import org.scribe.model.*;
/**
* @author Boris G. Tsirkin <mail@dotbg.name>
* @since 20.4.2011
*/
public class VkontakteApi extends DefaultApi20
{
private static final String AUTHORIZE_URL = "https://api.vkontakte.ru/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code";
private static final String SCOPED_AUTHORIZE_URL = String.format("%s&scope=%%s", AUTHORIZE_URL);
@Override
public String getAccessTokenEndpoint()
{
return "https://api.vkontakte.ru/oauth/access_token";
}
@Override
public String getAuthorizationUrl(OAuthConfig config)
{
Preconditions.checkValidUrl(config.getCallback(), "Valid url is required for a callback. Vkontakte does not support OOB");
if(config.hasScope())// Appending scope if present
{
return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), OAuthEncoder.encode(config.getScope()));
}
else
{
return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()));
}
}
@Override
public AccessTokenExtractor getAccessTokenExtractor()
{
return new JsonTokenExtractor();
}
}
@@ -1,33 +1,26 @@
package org.scribe.builder.api;
import org.scribe.model.*;
import org.scribe.services.*;
import org.scribe.model.Token;
public class YammerApi extends DefaultApi10a
{
private static final String AUTHORIZATION_URL = "'https://www.yammer.com/oauth/authorize?oauth_token=%s'";
@Override
public String getRequestTokenEndpoint()
@Override
public String getRequestTokenEndpoint()
{
return "https://www.yammer.com/oauth/request_token";
}
return "https://www.yammer.com/oauth/request_token";
}
@Override
public String getAccessTokenEndpoint()
@Override
public String getAccessTokenEndpoint()
{
return "https://www.yammer.com/oauth/access_token";
}
@Override
public String getAuthorizationUrl(Token requestToken)
{
return String.format(AUTHORIZATION_URL, requestToken.getToken());
}
@Override
public SignatureService getSignatureService()
{
return new PlaintextSignatureService();
}
return "https://www.yammer.com/oauth/access_token";
}
@Override
public String getAuthorizationUrl(Token requestToken)
{
return String.format(AUTHORIZATION_URL, requestToken.getToken());
}
}
@@ -1,5 +1,7 @@
package org.scribe.extractors;
import java.util.*;
import org.scribe.exceptions.*;
import org.scribe.model.*;
import org.scribe.utils.*;
@@ -21,19 +23,40 @@ public class BaseStringExtractorImpl implements BaseStringExtractor
public String extract(OAuthRequest request)
{
checkPreconditions(request);
String verb = OAuthEncoder.encode(request.getVerb().name());
String url = OAuthEncoder.encode(request.getSanitizedUrl());
String verb = URLUtils.percentEncode(request.getVerb().name());
String url = URLUtils.percentEncode(request.getSanitizedUrl());
String params = getSortedAndEncodedParams(request);
return String.format(AMPERSAND_SEPARATED_STRING, verb, url, params);
}
private String getSortedAndEncodedParams(OAuthRequest request)
{
ParameterList params = new ParameterList();
params.addAll(request.getQueryStringParams());
params.addAll(request.getBodyParams());
params.addAll(new ParameterList(request.getOauthParameters()));
return params.sort().asOauthBaseString();
Map<String, String> params = new HashMap<String, String>();
Map<String, String> tmp = null;
//params.putAll(request.getQueryStringParams());
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);
return URLUtils.percentEncode(URLUtils.concatSortedPercentEncodedParams(params));
}
private void checkPreconditions(OAuthRequest request)
@@ -32,7 +32,7 @@ public class HeaderExtractorImpl implements HeaderExtractor
{
header.append(PARAM_SEPARATOR);
}
header.append(String.format("%s=\"%s\"", key, OAuthEncoder.encode(parameters.get(key))));
header.append(String.format("%s=\"%s\"", key, URLUtils.percentEncode(parameters.get(key))));
}
return header.toString();
}
@@ -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*\"(\\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), "", response);
}
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=([^&]+)";
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.find())
{
String token = OAuthEncoder.decode(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
{
private static final Pattern TOKEN_REGEX = Pattern.compile("oauth_token=([^&]+)");
private static final Pattern SECRET_REGEX = Pattern.compile("oauth_token_secret=([^&]+)");
private static final String TOKEN_REGEX = "oauth_token=(\\S*)&oauth_token_secret=(\\S*?)(&(.*))?";
/**
* {@inheritDoc}
@@ -24,21 +23,16 @@ public class TokenExtractorImpl implements RequestTokenExtractor, AccessTokenExt
public Token extract(String response)
{
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 = p.matcher(response);
if (matcher.find() && matcher.groupCount() >= 1)
Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response);
if (matcher.matches())
{
return OAuthEncoder.decode(matcher.group(1));
}
else
String token = URLUtils.urlDecodeWrapper(matcher.group(1));
String secret = URLUtils.urlDecodeWrapper(matcher.group(2));
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 -44
View File
@@ -1,7 +1,5 @@
package org.scribe.model;
import java.io.*;
/**
* Parameter object that groups OAuth config values
*
@@ -9,26 +7,20 @@ import java.io.*;
*/
public class OAuthConfig
{
private final String apiKey;
private final String apiSecret;
private final String callback;
private final SignatureType signatureType;
private final String scope;
private final OutputStream debugStream;
private String apiKey;
private String apiSecret;
private String callback;
public OAuthConfig(String key, String secret)
{
this(key, secret, null, null, null, null);
this(key,secret,null);
}
public OAuthConfig(String key, String secret, String callback, SignatureType type, String scope, OutputStream stream)
public OAuthConfig(String key, String secret, String callback)
{
this.apiKey = key;
this.apiSecret = secret;
this.callback = callback;
this.signatureType = type;
this.scope = scope;
this.debugStream = stream;
}
public String getApiKey()
@@ -36,44 +28,28 @@ public class OAuthConfig
return apiKey;
}
public void setApiKey(String apiKey)
{
this.apiKey = apiKey;
}
public String getApiSecret()
{
return apiSecret;
}
public void setApiSecret(String apiSecret)
{
this.apiSecret = apiSecret;
}
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;
}
public void log(String message)
{
if (debugStream != null)
{
message = message + "\n";
try
{
debugStream.write(message.getBytes("UTF8"));
}
catch (Exception e)
{
// do nothing.
}
}
}
}
}
@@ -41,9 +41,4 @@ public class OAuthConstants
//OAuth 2.0
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;
import java.net.MalformedURLException;
import java.util.*;
/**
@@ -19,8 +20,9 @@ public class OAuthRequest extends Request
*
* @param verb Http verb/method
* @param url resource URL
* @throws MalformedURLException
*/
public OAuthRequest(Verb verb, String url)
public OAuthRequest(Verb verb, String url) throws MalformedURLException
{
super(verb, url);
this.oauthParameters = new HashMap<String, String>();
@@ -1,50 +0,0 @@
package org.scribe.model;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.scribe.exceptions.OAuthException;
import org.scribe.utils.OAuthEncoder;
/**
* @author: Pablo Fernandez
*/
public class Parameter implements Comparable<Parameter>
{
private static final String UTF = "UTF8";
private final String key;
private final String value;
public Parameter(String key, String value)
{
this.key = key;
this.value = value;
}
public String asUrlEncodedPair()
{
return OAuthEncoder.encode(key).concat("=").concat(OAuthEncoder.encode(value));
}
public boolean equals(Object other)
{
if(other == null) return false;
if(other == this) return true;
if(!(other instanceof Parameter)) return false;
Parameter otherParam = (Parameter) other;
return otherParam.key.equals(key) && otherParam.value.equals(value);
}
public int hashCode()
{
return key.hashCode() + value.hashCode();
}
public int compareTo(Parameter parameter)
{
int keyDiff = key.compareTo(parameter.key);
return keyDiff != 0 ? keyDiff : value.compareTo(parameter.value);
}
}
@@ -1,123 +0,0 @@
package org.scribe.model;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.scribe.utils.OAuthEncoder;
import org.scribe.utils.Preconditions;
/**
* @author: Pablo Fernandez
*/
public class ParameterList
{
private static final char QUERY_STRING_SEPARATOR = '?';
private static final String PARAM_SEPARATOR = "&";
private static final String PAIR_SEPARATOR = "=";
private static final String EMPTY_STRING = "";
private final List<Parameter> params;
public ParameterList()
{
params = new ArrayList<Parameter>();
}
ParameterList(List<Parameter> params)
{
this.params = new ArrayList<Parameter>(params);
}
public ParameterList(Map<String, String> map)
{
this();
for(Map.Entry<String, String> entry : map.entrySet())
{
params.add(new Parameter(entry.getKey(), entry.getValue()));
}
}
public void add(String key, String value)
{
params.add(new Parameter(key, value));
}
public String appendTo(String url)
{
Preconditions.checkNotNull(url, "Cannot append to null URL");
String queryString = asFormUrlEncodedString();
if (queryString.equals(EMPTY_STRING))
{
return url;
}
else
{
url += url.indexOf(QUERY_STRING_SEPARATOR) != -1 ? PARAM_SEPARATOR : QUERY_STRING_SEPARATOR;
url += queryString;
return url;
}
}
public String asOauthBaseString()
{
try
{
return URLEncoder.encode(asFormUrlEncodedString(), "UTF8");
}
catch (UnsupportedEncodingException uee)
{
throw new RuntimeException();
}
}
public String asFormUrlEncodedString()
{
if (params.size() == 0) return EMPTY_STRING;
StringBuilder builder = new StringBuilder();
for(Parameter p : params)
{
builder.append('&').append(p.asUrlEncodedPair());
}
return builder.toString().substring(1);
}
public void addAll(ParameterList other)
{
params.addAll(other.params);
}
public void addQuerystring(String queryString)
{
if (queryString != null && queryString.length() > 0)
{
for (String param : queryString.split(PARAM_SEPARATOR))
{
String pair[] = param.split(PAIR_SEPARATOR);
String key = OAuthEncoder.decode(pair[0]);
String value = pair.length > 1 ? OAuthEncoder.decode(pair[1]) : EMPTY_STRING;
params.add(new Parameter(key, value));
}
}
}
public boolean contains(Parameter param)
{
return params.contains(param);
}
public int size()
{
return params.size();
}
public ParameterList sort()
{
ParameterList sorted = new ParameterList(params);
Collections.sort(sorted.params);
return sorted;
}
}
+48 -144
View File
@@ -2,11 +2,11 @@ package org.scribe.model;
import java.io.*;
import java.net.*;
import java.nio.charset.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
import org.scribe.exceptions.*;
import org.scribe.utils.*;
/**
* Represents an HTTP Request object
@@ -16,34 +16,28 @@ import org.scribe.exceptions.*;
class Request
{
private static final String CONTENT_LENGTH = "Content-Length";
private static final String CONTENT_TYPE = "Content-Type";
public static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded";
private String url;
private URL url;
private Verb verb;
private ParameterList querystringParams;
private ParameterList bodyParams;
private Map<String, String> querystringParams;
private Map<String, String> bodyParams;
private Map<String, String> headers;
private String payload = null;
private HttpURLConnection connection;
private String charset;
private byte[] bytePayload = null;
private boolean connectionKeepAlive = false;
private Long connectTimeout = null;
private Long readTimeout = null;
/**
* Creates a new Http Request
*
* @param verb Http Verb (GET, POST, etc)
* @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.url = url;
this.querystringParams = new ParameterList();
this.bodyParams = new ParameterList();
this.url = new URL(url);
this.querystringParams = new HashMap<String, String>();
this.bodyParams = new HashMap<String, String>();
this.headers = new HashMap<String, String>();
}
@@ -60,52 +54,28 @@ class Request
{
createConnection();
return doSend();
}
catch (UnknownHostException uhe)
} catch (IOException ioe)
{
throw new OAuthException("Could not reach the desired host. Check your network connection.", uhe);
}
catch (IOException ioe)
{
throw new OAuthException("Problems while creating connection.", ioe);
throw new OAuthException("Problems while creating connection", ioe);
}
}
private void createConnection() throws IOException
{
String completeUrl = getCompleteUrl();
String effectiveUrl = URLUtils.appendParametersToQueryString(url.toString(), querystringParams);
if (connection == null)
{
System.setProperty("http.keepAlive", connectionKeepAlive ? "true" : "false");
connection = (HttpURLConnection) new URL(completeUrl).openConnection();
connection = (HttpURLConnection) new URL(effectiveUrl).openConnection();
}
}
/**
* Returns the complete url (host + resource + encoded querystring parameters).
*
* @return the complete url.
*/
public String getCompleteUrl()
{
return querystringParams.appendTo(url);
}
Response doSend() throws IOException
{
connection.setRequestMethod(this.verb.name());
if (connectTimeout != null)
{
connection.setConnectTimeout(connectTimeout.intValue());
}
if (readTimeout != null)
{
connection.setReadTimeout(readTimeout.intValue());
}
addHeaders(connection);
if (verb.equals(Verb.PUT) || verb.equals(Verb.POST))
{
addBody(connection, getByteBodyContents());
addBody(connection, getBodyContents());
}
return new Response(connection);
}
@@ -116,17 +86,11 @@ class Request
conn.setRequestProperty(key, headers.get(key));
}
void addBody(HttpURLConnection conn, byte[] content) throws IOException
void addBody(HttpURLConnection conn, String content) throws IOException
{
conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.length));
// Set default content type if none is set.
if (conn.getRequestProperty(CONTENT_TYPE) == null)
{
conn.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
}
conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.getBytes().length));
conn.setDoOutput(true);
conn.getOutputStream().write(content);
conn.getOutputStream().write(content.getBytes());
}
/**
@@ -148,7 +112,7 @@ class Request
*/
public void addBodyParameter(String key, String value)
{
this.bodyParams.add(key, value);
this.bodyParams.put(key, value);
}
/**
@@ -159,7 +123,7 @@ class Request
*/
public void addQuerystringParameter(String key, String value)
{
this.querystringParams.add(key, value);
this.querystringParams.put(key, value);
}
/**
@@ -178,43 +142,36 @@ class Request
}
/**
* Overloaded version for byte arrays
*
* @param payload
* Get a {@link Map} of the query string parameters.
*
* @return a map containing the query string parameters
*/
public void addPayload(byte[] payload)
public Map<String, String> getQueryStringParams()
{
this.bytePayload = payload;
Map<String, String> params = new HashMap<String, String>();
String query = url.getQuery();
if (query != null)
{
for (String param : query.split("&"))
{
String pair[] = param.split("=");
String valuePart = "";
if (pair.length > 1) {
valuePart = URLUtils.urlDecodeWrapper(pair[1]);
}
params.put(URLUtils.urlDecodeWrapper(pair[0]),valuePart );
}
}
params.putAll(querystringParams);
return params;
}
/**
* Get a {@link ParameterList} with the query string parameters.
* Obtains a {@link Map} of the body parameters.
*
* @return a {@link ParameterList} containing the query string parameters.
* @throws OAuthException if the request URL is not valid.
* @return a map containing the body parameters.
*/
public ParameterList getQueryStringParams()
{
try
{
ParameterList result = new ParameterList();
String queryString = new URL(url).getQuery();
result.addQuerystring(queryString);
result.addAll(querystringParams);
return result;
}
catch (MalformedURLException mue)
{
throw new OAuthException("Malformed URL", mue);
}
}
/**
* Obtains a {@link ParameterList} of the body parameters.
*
* @return a {@link ParameterList}containing the body parameters.
*/
public ParameterList getBodyParams()
public Map<String, String> getBodyParams()
{
return bodyParams;
}
@@ -226,7 +183,7 @@ class Request
*/
public String getUrl()
{
return url;
return url.toString();
}
/**
@@ -236,39 +193,17 @@ class Request
*/
public String getSanitizedUrl()
{
return url.replaceAll("\\?.*", "").replace("\\:\\d{4}", "");
return URLUtils.convertUrlToBaseStringURI(url);
}
/**
* Returns the body of the request
*
* @return form encoded string
* @throws OAuthException if the charset chosen is not supported
*/
public String getBodyContents()
{
try
{
return new String(getByteBodyContents(),getCharset());
}
catch(UnsupportedEncodingException uee)
{
throw new OAuthException("Unsupported Charset: "+charset, uee);
}
}
byte[] getByteBodyContents()
{
if (bytePayload != null) return bytePayload;
String body = (payload != null) ? payload : bodyParams.asFormUrlEncodedString();
try
{
return body.getBytes(getCharset());
}
catch(UnsupportedEncodingException uee)
{
throw new OAuthException("Unsupported Charset: "+getCharset(), uee);
}
return (payload != null) ? payload : URLUtils.formURLEncodeMap(bodyParams);
}
/**
@@ -291,16 +226,6 @@ class Request
return headers;
}
/**
* Returns the connection charset. Defaults to {@link Charset} defaultCharset if not set
*
* @return charset
*/
public String getCharset()
{
return charset == null ? Charset.defaultCharset().name() : charset;
}
/**
* Sets the connect timeout for the underlying {@link HttpURLConnection}
*
@@ -310,7 +235,7 @@ class Request
*/
public void setConnectTimeout(int duration, TimeUnit unit)
{
this.connectTimeout = unit.toMillis(duration);
this.connection.setConnectTimeout((int) unit.toMillis(duration));
}
/**
@@ -322,30 +247,9 @@ class Request
*/
public void setReadTimeout(int duration, TimeUnit unit)
{
this.readTimeout = unit.toMillis(duration);
this.connection.setReadTimeout((int) unit.toMillis(duration));
}
/**
* Set the charset of the body of the request
*
* @param charsetName name of the charset of the request
*/
public void setCharset(String charsetName)
{
this.charset = charsetName;
}
/**
* Sets whether the underlying Http Connection is persistent or not.
*
* @see http://download.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html
* @param connectionKeepAlive
*/
public void setConnectionKeepAlive(boolean connectionKeepAlive)
{
this.connectionKeepAlive = connectionKeepAlive;
}
/*
* We need this in order to stub the connection object for test cases
*/
+7 -7
View File
@@ -27,12 +27,11 @@ public class Response
connection.connect();
code = connection.getResponseCode();
headers = parseHeaders(connection);
stream = isSuccessful() ? connection.getInputStream() : connection.getErrorStream();
}
catch (UnknownHostException e)
stream = wasSuccessful() ? connection.getInputStream() : connection.getErrorStream();
} catch (UnknownHostException e)
{
code = 404;
body = Response.EMPTY;
body = EMPTY;
}
}
@@ -52,7 +51,7 @@ public class Response
return headers;
}
public boolean isSuccessful()
private boolean wasSuccessful()
{
return getCode() >= 200 && getCode() < 400;
}
@@ -101,9 +100,10 @@ public class Response
/**
* Obtains a single HTTP Header value, or null if undefined
*
* @param name the header name.
* @param header
* name
*
* @return header value or null.
* @return header value or null
*/
public String getHeader(String name)
{
@@ -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 secret;
private final String rawResponse;
/**
* Default constructor
@@ -22,15 +21,9 @@ public class Token implements Serializable
* @param secret token secret
*/
public Token(String token, String secret)
{
this(token, secret, null);
}
public Token(String token, String secret, String rawResponse)
{
this.token = token;
this.secret = secret;
this.rawResponse = rawResponse;
}
public String getToken()
@@ -43,15 +36,6 @@ public class Token implements Serializable
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
public String toString()
{
+3 -3
View File
@@ -1,7 +1,5 @@
package org.scribe.model;
import org.scribe.utils.*;
/**
* Represents an OAuth verifier code.
*
@@ -19,7 +17,9 @@ public class Verifier
*/
public Verifier(String value)
{
Preconditions.checkNotNull(value, "Must provide a valid string as verifier");
if (value == null) {
throw new IllegalArgumentException();
}
this.value = value;
}
@@ -1,10 +1,10 @@
package org.scribe.oauth;
import java.util.*;
import java.net.MalformedURLException;
import org.scribe.builder.api.*;
import org.scribe.exceptions.OAuthException;
import org.scribe.model.*;
import org.scribe.utils.*;
/**
* OAuth 1.0a implementation of {@link OAuthService}
@@ -13,10 +13,12 @@ import org.scribe.utils.*;
*/
public class OAuth10aServiceImpl implements OAuthService
{
private static final String NO_SCOPE = null;
private static final String VERSION = "1.0";
private OAuthConfig config;
private DefaultApi10a api;
private String scope;
/**
* Default constructor
@@ -28,6 +30,7 @@ public class OAuth10aServiceImpl implements OAuthService
{
this.api = api;
this.config = config;
this.scope = NO_SCOPE;
}
/**
@@ -35,21 +38,16 @@ public class OAuth10aServiceImpl implements OAuthService
*/
public Token getRequestToken()
{
config.log("obtaining request token from " + api.getRequestTokenEndpoint());
OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint());
config.log("setting oauth_callback to " + config.getCallback());
request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback());
OAuthRequest request = null;;
try {
request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint());
} catch (MalformedURLException e) {
throw new OAuthException("Problems while creating connection", e);
}
addOAuthParams(request, OAuthConstants.EMPTY_TOKEN);
appendSignature(request);
config.log("sending request...");
addOAuthHeader(request);
Response response = request.send();
String body = response.getBody();
config.log("response status code: " + response.getCode());
config.log("response body: " + body);
return api.getRequestTokenExtractor().extract(body);
return api.getRequestTokenExtractor().extract(response.getBody());
}
private void addOAuthParams(OAuthRequest request, Token token)
@@ -59,10 +57,9 @@ public class OAuth10aServiceImpl implements OAuthService
request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey());
request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod());
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));
config.log("appended additional OAuth parameters: " + MapUtils.toString(request.getOauthParameters()));
}
/**
@@ -70,14 +67,16 @@ public class OAuth10aServiceImpl implements OAuthService
*/
public Token getAccessToken(Token requestToken, Verifier verifier)
{
config.log("obtaining access token from " + api.getAccessTokenEndpoint());
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.VERIFIER, verifier.getValue());
config.log("setting token to: " + requestToken + " and verifier to: " + verifier);
addOAuthParams(request, requestToken);
appendSignature(request);
addOAuthHeader(request);
Response response = request.send();
return api.getAccessTokenExtractor().extract(response.getBody());
}
@@ -87,12 +86,9 @@ public class OAuth10aServiceImpl implements OAuthService
*/
public void signRequest(Token token, OAuthRequest request)
{
config.log("signing request: " + request.getCompleteUrl());
request.addOAuthParameter(OAuthConstants.TOKEN, token.getToken());
config.log("setting token to: " + token);
addOAuthParams(request, token);
appendSignature(request);
addOAuthHeader(request);
}
/**
@@ -103,6 +99,14 @@ public class OAuth10aServiceImpl implements OAuthService
return VERSION;
}
/**
* {@inheritDoc}
*/
public void addScope(String scope)
{
this.scope = scope;
}
/**
* {@inheritDoc}
*/
@@ -113,33 +117,13 @@ public class OAuth10aServiceImpl implements OAuthService
private String getSignature(OAuthRequest request, Token token)
{
config.log("generating signature...");
String baseString = api.getBaseStringExtractor().extract(request);
String signature = api.getSignatureService().getSignature(baseString, config.getApiSecret(), token.getSecret());
config.log("base string is: " + baseString);
config.log("signature is: " + signature);
return signature;
return api.getSignatureService().getSignature(baseString, config.getApiSecret(), token.getSecret());
}
private void appendSignature(OAuthRequest request)
private void addOAuthHeader(OAuthRequest request)
{
switch (config.getSignatureType())
{
case Header:
config.log("using Http Header signature");
String oauthHeader = api.getHeaderExtractor().extract(request);
request.addHeader(OAuthConstants.HEADER, oauthHeader);
break;
case QueryString:
config.log("using Querystring signature");
for (Map.Entry<String, String> entry : request.getOauthParameters().entrySet())
{
request.addQuerystringParameter(entry.getKey(), entry.getValue());
}
break;
}
String oauthHeader = api.getHeaderExtractor().extract(request);
request.addHeader(OAuthConstants.HEADER, oauthHeader);
}
}
@@ -22,19 +22,20 @@ public class OAuth20ServiceImpl implements OAuthService
this.config = config;
}
/**
* {@inheritDoc}
*/
public void addScope(String scope)
{
throw new UnsupportedOperationException("OAuth 2 does not use scopes");
}
/**
* {@inheritDoc}
*/
public Token getAccessToken(Token requestToken, Verifier verifier)
{
OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
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());
throw new UnsupportedOperationException("Unsupported operation, please use 'getAuthorizationUrl' and redirect your users there");
}
/**
@@ -41,6 +41,13 @@ public interface OAuthService
* @return oauth version as string
*/
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
@@ -30,7 +30,7 @@ public class HMACSha1SignatureService implements SignatureService
{
Preconditions.checkEmptyString(baseString, "Base string cant be null or empty string");
Preconditions.checkEmptyString(apiSecret, "Api secret cant be null or empty string");
return doSign(baseString, OAuthEncoder.encode(apiSecret) + '&' + OAuthEncoder.encode(tokenSecret));
return doSign(baseString, URLUtils.percentEncode(apiSecret) + '&' + URLUtils.percentEncode(tokenSecret));
}
catch (Exception e)
{
@@ -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 OAuthEncoder.encode(apiSecret) + '&' + OAuthEncoder.encode(tokenSecret);
}
catch (Exception e)
{
throw new OAuthSignatureException(baseString, e);
}
}
/**
* {@inheritDoc}
*/
public String getSignatureMethod()
{
return METHOD;
}
}
+23 -9
View File
@@ -1,22 +1,36 @@
package org.scribe.utils;
import java.util.Map;
import java.util.*;
/**
* @author: Pablo Fernandez
* Utils for {@link Map} manipulation
*
* @author Pablo Fernandez
*/
public class MapUtils
{
public static <K,V> String toString(Map<K,V> map)
/**
* Sorts a Map
*
* @param map unsorted map
* @return sorted map
*/
public static final Map<String, String> sort(Map<String, String> map)
{
if (map == null) return "";
if (map.isEmpty()) return "{}";
Preconditions.checkNotNull(map, "Cannot sort a null object.");
StringBuilder result = new StringBuilder();
for(Map.Entry<K,V> entry : map.entrySet())
Map<String, String> sorted = new LinkedHashMap<String, String>();
for (String key : getSortedKeys(map))
{
result.append(String.format(", %s -> %s ", entry.getKey().toString(), entry.getValue().toString()));
sorted.put(key, map.get(key));
}
return "{" + result.substring(1) + "}";
return sorted;
}
private static List<String> getSortedKeys(Map<String, String> map)
{
List<String> keys = new ArrayList<String>(map.keySet());
Collections.sort(keys);
return keys;
}
}
@@ -1,62 +0,0 @@
package org.scribe.utils;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import org.scribe.exceptions.*;
/**
* @author: Pablo Fernandez
*/
public class OAuthEncoder
{
private static String CHARSET = "UTF-8";
private static final Map<String, String> ENCODING_RULES;
static
{
Map<String, String> rules = new HashMap<String, String>();
rules.put("*", "%2A");
rules.put("+", "%20");
rules.put("%7E", "~");
ENCODING_RULES = Collections.unmodifiableMap(rules);
}
public static String encode(String plain)
{
Preconditions.checkNotNull(plain, "Cannot encode null object");
String encoded = "";
try
{
encoded = URLEncoder.encode(plain, CHARSET);
}
catch (UnsupportedEncodingException uee)
{
throw new OAuthException("Charset not found while encoding string: " + CHARSET, uee);
}
for(Map.Entry<String, String> rule : ENCODING_RULES.entrySet())
{
encoded = applyRule(encoded, rule.getKey(), rule.getValue());
}
return encoded;
}
private static String applyRule(String encoded, String toReplace, String replacement)
{
return encoded.replaceAll(Pattern.quote(toReplace), replacement);
}
public static String decode(String encoded)
{
Preconditions.checkNotNull(encoded, "Cannot decode null object");
try
{
return URLDecoder.decode(encoded, CHARSET);
}
catch(UnsupportedEncodingException uee)
{
throw new OAuthException("Charset not found while decoding string: " + CHARSET, uee);
}
}
}
@@ -0,0 +1,198 @@
package org.scribe.utils;
import java.io.*;
import java.net.*;
import java.util.*;
/**
* Utils to deal with URL and url-encodings
*
* @author Pablo Fernandez
*/
public class URLUtils
{
private static final String EMPTY_STRING = "";
private static final String UTF_8 = "UTF-8";
private static final char PAIR_SEPARATOR = '=';
private static final char PARAM_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 Set<EncodingRule> ENCODING_RULES;
static
{
Set<EncodingRule> rules = new HashSet<EncodingRule>();
rules.add(new EncodingRule("*","%2A"));
rules.add(new EncodingRule("+","%20"));
rules.add(new EncodingRule("%7E", "~"));
ENCODING_RULES = Collections.unmodifiableSet(rules);
}
/**
* Turns a map into a form-url-encoded string (key=value&key2&key3=value)
*
* @param map any map
* @return form-url-encoded string
*/
public static String formURLEncodeMap(Map<String, String> map)
{
Preconditions.checkNotNull(map, "Cannot url-encode a null object");
return (map.size() <= 0) ? EMPTY_STRING : doFormUrlEncode(map);
}
private static String doFormUrlEncode(Map<String, String> map)
{
StringBuffer encodedString = new StringBuffer(map.size() * 20);
for (String key : map.keySet())
{
if(encodedString.length() > 0)
{
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();
}
/**
* Percent encodes a string
*
* @param plain
* @return percent encoded string
*/
public static String percentEncode(String string)
{
Preconditions.checkNotNull(string, "Cannot encode null string");
try
{
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);
}
}
/**
* URL encodes a string
*
* @param plain
* @return percent encoded string
*/
public static String urlEncodeWrapper(String string)
{
Preconditions.checkNotNull(string, "Cannot encode null string");
try
{
return URLEncoder.encode(string, UTF_8);
}
catch (UnsupportedEncodingException uee)
{
throw new IllegalStateException(ERROR_MSG, uee);
}
}
/**
* URL decodes a string
*
* @param string percent encoded string
* @return plain string
*/
public static String urlDecodeWrapper(String string)
{
Preconditions.checkNotNull(string, "Cannot decode null string");
try
{
return URLDecoder.decode(string, UTF_8);
}
catch (UnsupportedEncodingException uee)
{
throw new IllegalStateException(ERROR_MSG, uee);
}
}
/**
* Append given parameters to the query string of the url
*
* @param url the url to append parameters to
* @param params any map
* @return new url with parameters on query string
*/
public static String appendParametersToQueryString(String url, Map<String, String> params)
{
Preconditions.checkNotNull(url, "Cannot append to null URL");
String queryString = URLUtils.formURLEncodeMap(params);
if (queryString.length() == 0) return url;
// Check if there are parameters in the url already and use '&' instead of '?'
url += url.indexOf(QUERY_STRING_SEPARATOR) != -1 ? PARAM_SEPARATOR : QUERY_STRING_SEPARATOR;
url += queryString;
return url;
}
private static final class EncodingRule
{
private final String ch;
private final String toCh;
EncodingRule(String ch, String toCh)
{
this.ch = ch;
this.toCh = toCh;
}
String apply(String string) {
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
public void shouldReturnConfigDefaultValues()
public void shouldReturnOOBasDefaultCallback()
{
builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").build();
assertEquals(ApiMock.config.getApiKey(), "key");
assertEquals(ApiMock.config.getApiSecret(), "secret");
assertEquals(ApiMock.config.getCallback(), OAuthConstants.OUT_OF_BAND);
assertEquals(ApiMock.config.getSignatureType(), SignatureType.Header);
}
@Test
@@ -36,15 +35,6 @@ public class ServiceBuilderTest
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)
public void shouldNotAcceptAnInvalidUrlAsCallback()
{
@@ -57,16 +47,19 @@ public class ServiceBuilderTest
builder.provider(ApiMock.class).apiKey("key").apiSecret("secret").scope("rss-api").build();
assertEquals(ApiMock.config.getApiKey(), "key");
assertEquals(ApiMock.config.getApiSecret(), "secret");
assertEquals(ApiMock.config.getScope(), "rss-api");
assertEquals(ApiMock.scope, "rss-api");
}
public static class ApiMock implements Api
{
public static OAuthConfig config;
public OAuthService createService(OAuthConfig config)
public static String scope;
@Override
public OAuthService createService(OAuthConfig config, String scope)
{
ApiMock.config = config;
ApiMock.scope = scope;
return null;
}
}
@@ -1,5 +1,6 @@
package org.scribe.examples;
import java.net.MalformedURLException;
import java.util.*;
import org.scribe.builder.*;
@@ -11,12 +12,13 @@ public class FacebookExample
{
private static final String NETWORK_NAME = "Facebook";
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;
public static void main(String[] args)
public static void main(String[] args) throws MalformedURLException
{
// Replace these with your own api key and secret
String apiKey = "your_app_id";
String apiKey = "your_api_key";
String apiSecret = "your_api_secret";
OAuthService service = new ServiceBuilder()
.provider(FacebookApi.class)
@@ -35,16 +37,9 @@ public class FacebookExample
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.println("And paste the access token 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 + " )");
Token accessToken = new Token(in.nextLine(), NO_SECRET_NEEDED);
System.out.println();
// 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;
import java.net.MalformedURLException;
import java.util.Scanner;
import org.scribe.builder.*;
@@ -11,7 +12,7 @@ public class FoursquareExample
{
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()
.provider(FoursquareApi.class)
@@ -1,5 +1,6 @@
package org.scribe.examples;
import java.net.MalformedURLException;
import java.util.*;
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 SCOPE = "https://docs.google.com/feeds/";
public static void main(String[] args)
public static void main(String[] args) throws MalformedURLException
{
OAuthService service = new ServiceBuilder()
.provider(GoogleApi.class)
@@ -1,5 +1,6 @@
package org.scribe.examples;
import java.net.MalformedURLException;
import java.util.Scanner;
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)";
public static void main(String[] args)
public static void main(String[] args) throws MalformedURLException
{
OAuthService service = new ServiceBuilder()
.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 LiveExample
{
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 = "";
String apiSecret = "";
OAuthService service = new ServiceBuilder()
.provider(LiveApi.class)
.apiKey(apiKey)
.apiSecret(apiSecret)
.scope("wl.basic")
.callback("http://localhost:9000/")
.build();
Scanner in = new Scanner(System.in);
System.out.println("=== Windows Live'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,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,68 +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 NeteaseWeiboExample
{
private static final String NETWORK_NAME = "NetEase(163.com) Weibo";
private static final String PROTECTED_RESOURCE_URL = "http://api.t.163.com/account/verify_credentials.json";
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(NeteaseWeibooApi.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,68 +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 SinaWeiboExample
{
private static final String NETWORK_NAME = "SinaWeibo";
private static final String PROTECTED_RESOURCE_URL = "http://api.t.sina.com.cn/account/verify_credentials.json";
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(SinaWeiboApi.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,68 +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 SohuWeiboExample
{
private static final String NETWORK_NAME = "SohuWeibo";
private static final String PROTECTED_RESOURCE_URL = "http://api.t.sohu.com/account/verify_credentials.json";
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(SohuWeiboApi.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;
import java.net.MalformedURLException;
import java.util.Scanner;
import org.scribe.builder.*;
@@ -9,9 +10,9 @@ import org.scribe.oauth.*;
public class TwitterExample
{
private static final String PROTECTED_RESOURCE_URL = "https://api.twitter.com/1/statuses/update.json";
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()
.provider(TwitterApi.class)
@@ -45,8 +46,7 @@ public class TwitterExample
// 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.POST, PROTECTED_RESOURCE_URL);
request.addBodyParameter("status", "this is sparta! *");
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...");
@@ -1,68 +0,0 @@
package org.scribe.examples;
import org.scribe.builder.*;
import org.scribe.builder.api.*;
import org.scribe.model.*;
import org.scribe.oauth.*;
import java.util.*;
/**
* @author Boris G. Tsirkin <mail@dotbg.name>
* @since 20.4.2011
*/
public class VkontakteExample
{
private static final String NETWORK_NAME = "Vkontakte.ru";
private static final String PROTECTED_RESOURCE_URL = "https://api.vkontakte.ru/method/friends.get";
private static final Token EMPTY_TOKEN = null;
public static void main(String[] args)
{
// Replace these with your own api key and secret
final String clientId = "your app id";
final String apiSecret = "your api secret";
OAuthService service = new ServiceBuilder()
.provider(VkontakteApi.class)
.apiKey(clientId)
.apiSecret(apiSecret)
.scope("friends,wall,offline") // replace with desired scope
.callback("http://your.site.com/callback")
.build();
Scanner in = new Scanner(System.in);
System.out.println("=== " + NETWORK_NAME + "'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);
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;
import java.net.MalformedURLException;
import java.util.Scanner;
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";
public static void main(String[] args)
public static void main(String[] args) throws MalformedURLException
{
OAuthService service = new ServiceBuilder()
.provider(YahooApi.class)
@@ -2,6 +2,8 @@ package org.scribe.extractors;
import static org.junit.Assert.*;
import java.net.MalformedURLException;
import org.junit.*;
import org.scribe.exceptions.*;
import org.scribe.model.*;
@@ -12,12 +14,16 @@ public class BaseStringExtractorTest
private BaseStringExtractorImpl extractor;
private OAuthRequest request;
private OAuthRequest request2;
@Before
public void setup()
public void setup() throws MalformedURLException
{
request = ObjectMother.createSampleOAuthRequest();
request2 = ObjectMother.createSampleOAuthRequest2();
extractor = new BaseStringExtractorImpl();
}
@Test
@@ -27,6 +33,14 @@ public class BaseStringExtractorTest
String baseString = extractor.extract(request);
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)
public void shouldThrowExceptionIfRquestIsNull()
@@ -36,12 +50,12 @@ public class BaseStringExtractorTest
}
@Test(expected = OAuthParametersMissingException.class)
public void shouldThrowExceptionIfRquestHasNoOAuthParameters()
public void shouldThrowExceptionIfRquestHasNoOAuthParameters() throws MalformedURLException
{
OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com");
extractor.extract(request);
}
@Test
public void shouldProperlyEncodeSpaces()
{
@@ -2,6 +2,8 @@ package org.scribe.extractors;
import static org.junit.Assert.*;
import java.net.MalformedURLException;
import org.junit.*;
import org.scribe.exceptions.*;
import org.scribe.model.*;
@@ -14,7 +16,7 @@ public class HeaderExtractorTest
private OAuthRequest request;
@Before
public void setup()
public void setup() throws MalformedURLException
{
request = ObjectMother.createSampleOAuthRequest();
extractor = new HeaderExtractorImpl();
@@ -37,7 +39,7 @@ public class HeaderExtractorTest
}
@Test(expected = OAuthParametersMissingException.class)
public void shouldExceptionIfRequestHasNoOAuthParams()
public void shouldExceptionIfRequestHasNoOAuthParams() throws MalformedURLException
{
OAuthRequest emptyRequest = new OAuthRequest(Verb.GET, "http://example.com");
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,67 +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
public void shouldExtractTokenFromResponseWithManyParameters()
{
String response = "access_token=foo1234&other_stuff=yeah_we_have_this_too&number=42";
Token extracted = extractor.extract(response);
assertEquals("foo1234", 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());
}
@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
public void shouldExtractTokenFromResponseWithCallbackConfirmed()
{
@@ -22,12 +22,6 @@ public class ConnectionStub extends HttpURLConnection
headers.put(key, value);
}
@Override
public String getRequestProperty(String s)
{
return headers.get(s);
}
public Map<String, String> getHeaders()
{
return headers;
@@ -0,0 +1,26 @@
package org.scribe.model;
import static org.junit.Assert.*;
import org.junit.*;
public class OAuthConfigTest
{
@Test
public void shouldReturnDefaultValuesIfNotSet()
{
OAuthConfig config = new OAuthConfig("key", "secret");
assertEquals(OAuthConstants.OUT_OF_BAND, config.getCallback());
}
@Test
public void shouldOverrideDefaultsIfSet()
{
OAuthConfig config = new OAuthConfig("key", "secret", "http://callback");
assertEquals("http://callback", config.getCallback());
assertEquals("key", config.getApiKey());
assertEquals("secret", config.getApiSecret());
}
}
@@ -2,6 +2,8 @@ package org.scribe.model;
import static org.junit.Assert.*;
import java.net.MalformedURLException;
import org.junit.*;
public class OAuthRequestTest
@@ -10,7 +12,7 @@ public class OAuthRequestTest
private OAuthRequest request;
@Before
public void setup()
public void setup() throws MalformedURLException
{
request = new OAuthRequest(Verb.GET, "http://example.com");
}
@@ -1,91 +0,0 @@
package org.scribe.model;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
/**
* @author: Pablo Fernandez
*/
public class ParameterListTest
{
private ParameterList params;
@Before
public void setup()
{
this.params = new ParameterList();
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenAppendingNullMapToQuerystring()
{
String url = null;
params.appendTo(url);
}
@Test
public void shouldAppendNothingToQuerystringIfGivenEmptyMap()
{
String url = "http://www.example.com";
Assert.assertEquals(url, params.appendTo(url));
}
@Test
public void shouldAppendParametersToSimpleUrl()
{
String url = "http://www.example.com";
String expectedUrl = "http://www.example.com?param1=value1&param2=value%20with%20spaces";
params.add("param1", "value1");
params.add("param2", "value with spaces");
url = params.appendTo(url);
Assert.assertEquals(url, expectedUrl);
}
@Test
public void shouldAppendParametersToUrlWithQuerystring()
{
String url = "http://www.example.com?already=present";
String expectedUrl = "http://www.example.com?already=present&param1=value1&param2=value%20with%20spaces";
params.add("param1", "value1");
params.add("param2", "value with spaces");
url = params.appendTo(url);
Assert.assertEquals(url, expectedUrl);
}
@Test
public void shouldProperlySortParameters()
{
params.add("param1", "v1");
params.add("param6", "v2");
params.add("a_param", "v3");
params.add("param2", "v4");
Assert.assertEquals("a_param=v3&param1=v1&param2=v4&param6=v2", params.sort().asFormUrlEncodedString());
}
@Test
public void shouldProperlySortParametersWithTheSameName()
{
params.add("param1", "v1");
params.add("param6", "v2");
params.add("a_param", "v3");
params.add("param1", "v4");
Assert.assertEquals("a_param=v3&param1=v1&param1=v4&param6=v2", params.sort().asFormUrlEncodedString());
}
@Test
public void shouldNotModifyTheOriginalParameterList()
{
params.add("param1", "v1");
params.add("param6", "v2");
assertNotSame(params, params.sort());
}
}
+41 -55
View File
@@ -2,10 +2,13 @@ package org.scribe.model;
import static org.junit.Assert.*;
import java.net.MalformedURLException;
import org.junit.*;
public class RequestTest
{
private Request getRequest;
private Request postRequest;
private ConnectionStub connection;
@@ -15,8 +18,6 @@ public class RequestTest
{
connection = new ConnectionStub();
postRequest = new Request(Verb.POST, "http://example.com");
postRequest.addBodyParameter("param", "value");
postRequest.addBodyParameter("param with spaces", "value with spaces");
postRequest.setConnection(connection);
getRequest = new Request(Verb.GET, "http://example.com?qsparam=value&other+param=value+with+spaces");
getRequest.setConnection(connection);
@@ -34,7 +35,9 @@ public class RequestTest
{
assertEquals(2, getRequest.getQueryStringParams().size());
assertEquals(0, postRequest.getQueryStringParams().size());
assertTrue(getRequest.getQueryStringParams().contains(new Parameter("qsparam", "value")));
assertTrue(getRequest.getQueryStringParams().containsKey("qsparam"));
assertTrue(getRequest.getQueryStringParams().get("qsparam").equals("value"));
assertTrue(getRequest.getQueryStringParams().get("other param").equals("value with spaces"));
}
@Test
@@ -48,10 +51,12 @@ public class RequestTest
}
@Test
public void shouldSetBodyParamsAndAddContentLength()
public void shouldSetBodyParamsAndHeaders()
{
assertEquals("param=value&param%20with%20spaces=value%20with%20spaces", postRequest.getBodyContents());
postRequest.addBodyParameter("param", "value");
postRequest.addBodyParameter("param two", "value with spaces");
postRequest.send();
assertEquals("param+two=value+with+spaces&param=value", postRequest.getBodyContents());
assertTrue(connection.getHeaders().containsKey("Content-Length"));
}
@@ -65,7 +70,7 @@ public class RequestTest
}
@Test
public void shouldAllowAddingQuerystringParametersAfterCreation()
public void shouldAllowAddingQuerystringParametersAfterCreation() throws MalformedURLException
{
Request request = new Request(Verb.GET, "http://example.com?one=val");
request.addQuerystringParameter("two", "other val");
@@ -73,56 +78,37 @@ public class RequestTest
assertEquals(3, request.getQueryStringParams().size());
}
@Test
public void shouldReturnTheCompleteUrl()
@Test
public void sanatizeUrlTest() throws MalformedURLException
{
Request request = new Request(Verb.GET, "http://example.com?one=val");
request.addQuerystringParameter("two", "other val");
request.addQuerystringParameter("more", "params");
assertEquals("http://example.com?one=val&two=other%20val&more=params", request.getCompleteUrl());
}
@Test
public void shouldHandleQueryStringSpaceEncodingProperly()
{
assertTrue(getRequest.getQueryStringParams().contains(new Parameter("other param","value with spaces")));
}
@Test
public void shouldAutomaticallyAddContentTypeForPostRequestsWithBytePayload()
{
postRequest.addPayload("PAYLOAD".getBytes());
postRequest.send();
assertEquals(Request.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type"));
}
@Test
public void shouldAutomaticallyAddContentTypeForPostRequestsWithStringPayload()
{
postRequest.addPayload("PAYLOAD");
postRequest.send();
assertEquals(Request.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type"));
}
@Test
public void shouldAutomaticallyAddContentTypeForPostRequestsWithBodyParameters()
{
postRequest.send();
assertEquals(Request.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type"));
}
@Test
public void shouldBeAbleToOverrideItsContentType()
{
postRequest.addHeader("Content-Type", "my-content-type");
postRequest.send();
assertEquals("my-content-type", connection.getHeaders().get("Content-Type"));
}
@Test
public void shouldNotAddContentTypeForGetRequests()
{
getRequest.send();
assertFalse(connection.getHeaders().containsKey("Content-Type"));
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;
import java.net.MalformedURLException;
import org.scribe.model.*;
public class ObjectMother
{
public static OAuthRequest createSampleOAuthRequest()
public static OAuthRequest createSampleOAuthRequest() throws MalformedURLException
{
OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com");
request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456");
@@ -14,4 +16,14 @@ public class ObjectMother
request.addOAuthParameter(OAuthConstants.SIGNATURE, "OAuth-Signature");
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;
}
}
@@ -1,35 +1,53 @@
package org.scribe.utils;
import static org.junit.Assert.*;
import java.util.*;
import org.junit.*;
/**
* @author: Pablo Fernandez
*/
public class MapUtilsTest
{
@Test
public void shouldPrettyPrintMap()
private Map<String, String> unsorted;
@Before
public void setup()
{
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(4, "four");
Assert.assertEquals("{ 1 -> one , 2 -> two , 3 -> three , 4 -> four }", MapUtils.toString(map));
unsorted = new LinkedHashMap<String, String>();
unsorted.put("d", "fourth");
unsorted.put("a", "first");
unsorted.put("c", "third");
unsorted.put("b", "second");
}
@Test
public void shouldHandleEmptyMap()
public void shouldSortMap()
{
Map<Integer, String> map = new HashMap<Integer, String>();
Assert.assertEquals("{}", MapUtils.toString(map));
Map<String, String> sorted = MapUtils.sort(unsorted);
List<String> values = new ArrayList<String>(sorted.values());
assertEquals("first", values.get(0));
assertEquals("second", values.get(1));
assertEquals("third", values.get(2));
assertEquals("fourth", values.get(3));
}
@Test
public void shouldHandleNullInputs()
public void shouldNotModifyTheOriginalMap()
{
Assert.assertEquals("", MapUtils.toString(null));
Map<String, String> sorted = MapUtils.sort(unsorted);
assertNotSame(sorted, unsorted);
List<String> values = new ArrayList<String>(unsorted.values());
assertEquals("fourth", values.get(0));
assertEquals("first", values.get(1));
assertEquals("third", values.get(2));
assertEquals("second", values.get(3));
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionForNullMap()
{
MapUtils.sort(null);
}
}
@@ -1,70 +0,0 @@
package org.scribe.utils;
import org.junit.*;
import static org.junit.Assert.*;
/**
* @author: Pablo Fernandez
*/
public class OAuthEncoderTest
{
@Test
public void shouldPercentEncodeString()
{
String plain = "this is a test &^";
String encoded = "this%20is%20a%20test%20%26%5E";
assertEquals(encoded, OAuthEncoder.encode(plain));
}
@Test
public void shouldFormURLDecodeString()
{
String encoded = "this+is+a+test+%26%5E";
String plain = "this is a test &^";
assertEquals(plain, OAuthEncoder.decode(encoded));
}
@Test
public void shouldPercentEncodeAllSpecialCharacters()
{
String plain = "!*'();:@&=+$,/?#[]";
String encoded = "%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D";
assertEquals(encoded, OAuthEncoder.encode(plain));
assertEquals(plain, OAuthEncoder.decode(encoded));
}
@Test
public void shouldNotPercentEncodeReservedCharacters()
{
String plain = "abcde123456-._~";
String encoded = plain;
assertEquals(encoded, OAuthEncoder.encode(plain));
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfStringToEncodeIsNull()
{
String toEncode = null;
OAuthEncoder.encode(toEncode);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfStringToDecodeIsNull()
{
String toDecode = null;
OAuthEncoder.decode(toDecode);
}
@Test
public void shouldPercentEncodeCorrectlyTwitterCodingExamples()
{
// These tests are part of the Twitter dev examples here -> https://dev.twitter.com/docs/auth/percent-encoding-parameters
String sources[] = {"Ladies + Gentlemen", "An encoded string!", "Dogs, Cats & Mice"};
String encoded[] = {"Ladies%20%2B%20Gentlemen", "An%20encoded%20string%21", "Dogs%2C%20Cats%20%26%20Mice"};
for(int i = 0; i < sources.length; i++)
{
Assert.assertEquals(encoded[i], OAuthEncoder.encode(sources[i]));
}
}
}
@@ -0,0 +1,147 @@
package org.scribe.utils;
import static org.junit.Assert.*;
import java.util.*;
import org.junit.*;
public class URLUtilsTest
{
@Test
public void shouldPercentEncodeMap()
{
Map<String, String> params = new LinkedHashMap<String, String>();
params.put("key", "value");
params.put("key with spaces", "value with spaces");
params.put("&symbols!", "#!");
String expected = "key=value&key+with+spaces=value+with+spaces&%26symbols%21=%23%21";
assertEquals(expected, URLUtils.formURLEncodeMap(params));
}
@Test
public void shouldReturnEmptyStringForEmptyMap()
{
Map<String, String> params = new LinkedHashMap<String, String>();
String expected = "";
assertEquals(expected, URLUtils.formURLEncodeMap(params));
}
@Test
public void shouldPercentEncodeString()
{
String toEncode = "this is a test &^";
String expected = "this%20is%20a%20test%20%26%5E";
assertEquals(expected, URLUtils.percentEncode(toEncode));
}
@Test
public void shouldPercentDecodeString()
{
String toDecode = "this+is+a+test+%26%5E";
String expected = "this is a test &^";
assertEquals(expected, URLUtils.urlDecodeWrapper(toDecode));
}
@Test
public void shouldEncodeAllSpecialCharacters()
{
String plain = "!*'();:@&=+$,/?#[]";
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(plain, URLUtils.urlDecodeWrapper(encoded));
}
@Test
public void shouldNotEncodeReservedCharacters()
{
String plain = "abcde123456-._~";
String encoded = plain;
assertEquals(encoded, URLUtils.percentEncode(plain));
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfMapIsNull()
{
Map<String, String> nullMap = null;
URLUtils.formURLEncodeMap(nullMap);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfStringToEncodeIsNull()
{
String toEncode = null;
URLUtils.percentEncode(toEncode);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfStringToDecodeIsNull()
{
String toDecode = null;
URLUtils.urlDecodeWrapper(toDecode);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenAppendingNullMapToQuerystring()
{
String url = "http://www.example.com";
Map<String, String> nullMap = null;
URLUtils.appendParametersToQueryString(url, nullMap);
}
@Test
public void shouldAppendNothingToQuerystringIfGivenEmptyMap()
{
String url = "http://www.example.com";
Map<String, String> emptyMap = new HashMap<String, String>();
String newUrl = URLUtils.appendParametersToQueryString(url, emptyMap);
Assert.assertEquals(url, newUrl);
}
@Test
public void shouldAppendParametersToSimpleUrl()
{
String url = "http://www.example.com";
String expectedUrl = "http://www.example.com?param1=value1&param2=value+with+spaces";
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "value1");
params.put("param2", "value with spaces");
url = URLUtils.appendParametersToQueryString(url, params);
Assert.assertEquals(url, expectedUrl);
}
@Test
public void shouldAppendParametersToUrlWithQuerystring()
{
String url = "http://www.example.com?already=present";
String expectedUrl = "http://www.example.com?already=present&param1=value1&param2=value+with+spaces";
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "value1");
params.put("param2", "value with spaces");
url = URLUtils.appendParametersToQueryString(url, params);
Assert.assertEquals(url, expectedUrl);
}
@Test
public void shouldEncodePlusSymbol()
{
String plain = "7aEP+jNAwvjc0mjhqg0nuXPf";
String encoded = "7aEP%2BjNAwvjc0mjhqg0nuXPf";
Assert.assertEquals(encoded, URLUtils.percentEncode(plain));
}
@Test
public void shouldDecodePlusSymbol()
{
String encoded = "oauth_verifier=7aEP%2BjNAwvjc0mjhqg0nuXPf";
String expected = "oauth_verifier=7aEP+jNAwvjc0mjhqg0nuXPf";
Assert.assertEquals(expected, URLUtils.urlDecodeWrapper(encoded));
}
}