From 44fbcff29cd873284869edea1c20b6b5abea5b7d Mon Sep 17 00:00:00 2001 From: "ada.young" Date: Tue, 26 Apr 2016 13:15:12 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=BC=80=E6=BA=90?= =?UTF-8?q?=E4=B8=AD=E5=9B=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 492 ++++++++--------- scribejava-apis/pom.xml | 74 +-- .../github/scribejava/apis/OschinaApi.java | 69 +++ .../apis/service/OsChinaOAuthServiceImpl.java | 26 + scribejava-core/pom.xml | 58 +- .../scribejava/core/oauth/OAuth20Service.java | 500 +++++++++--------- 6 files changed, 655 insertions(+), 564 deletions(-) create mode 100644 scribejava-apis/src/main/java/com/github/scribejava/apis/OschinaApi.java create mode 100644 scribejava-apis/src/main/java/com/github/scribejava/apis/service/OsChinaOAuthServiceImpl.java diff --git a/pom.xml b/pom.xml index a87a5c4bf..958e8aa81 100644 --- a/pom.xml +++ b/pom.xml @@ -1,259 +1,233 @@ - - 4.0.0 - com.github.scribejava - scribejava - pom - 2.5.4-SNAPSHOT - ScribeJava OAuth Library - The best OAuth library out there - https://github.com/scribejava/scribejava - - - org.sonatype.oss - oss-parent - 9 - - - - scribejava-core - scribejava-apis - - - - - MIT - https://github.com/scribejava/scribejava/blob/master/LICENSE.txt - - - - - scm:git:git://github.com/scribejava/scribejava.git - scm:git:git@github.com:scribejava/scribejava.git - https://github.com/scribejava/scribejava - - - - - kullfar - Stas Gromov - s.gromov@hh.ru - hh.ru - http://hh.ru - - all - - +3 - - kullfar@jabber.ru - kullfar@gmail.com - +7-909-677-11-16 - - - - chernatkin - Sergey Chernatkin - s.chernatkin@hh.ru - hh.ru - http://hh.ru - - all - - +3 - - - igaranina - Irina Garanina - i.garanina@hh.ru - hh.ru - http://hh.ru - - all - - +3 - - - - - - junit - junit - 4.12 - test - - - com.google.code.gson - gson - 2.6.2 - test - - - commons-codec - commons-codec - 1.10 - compile - true - - - com.ning - async-http-client - 1.9.38 - provided - - - - - - - org.apache.felix - maven-bundle-plugin - 3.0.1 - - - bundle-manifest - process-classes - - manifest - - - - - - org.apache.maven.plugins - maven-jar-plugin - 2.6 - - - ${project.build.outputDirectory}/META-INF/MANIFEST.MF - - - - - - - - org.apache.maven.wagon - wagon-webdav - 1.0-beta-2 - - - - - maven-compiler-plugin - 3.5.1 - - UTF-8 - 1.7 - 1.7 - true - - - - maven-deploy-plugin - 2.8.2 - - - default-deploy - deploy - - deploy - - - - - - org.apache.maven.plugins - maven-resources-plugin - 2.7 - - UTF-8 - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.0 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - UTF-8 - - - - attach-javadoc - - jar - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 2.17 - - - com.puppycrawl.tools - checkstyle - 6.17 - - - - - validate - validate - - ${basedir}/src - checkstyle.xml - UTF-8 - true - - - check - - - - - - - - - - release-sign-artifacts - - - performRelease - true - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - - - - + + 4.0.0 + com.github.scribejava + scribejava + pom + 2.5.6-SNAPSHOT + ScribeJava OAuth Library + The best OAuth library out there + https://github.com/scribejava/scribejava + + + org.sonatype.oss + oss-parent + 9 + + + + scribejava-core + scribejava-apis + + + + + MIT + https://github.com/scribejava/scribejava/blob/master/LICENSE.txt + + + + + scm:git:git://github.com/scribejava/scribejava.git + scm:git:git@github.com:scribejava/scribejava.git + https://github.com/scribejava/scribejava + + + + + kullfar + Stas Gromov + s.gromov@hh.ru + hh.ru + http://hh.ru + + all + + +3 + + kullfar@jabber.ru + kullfar@gmail.com + +7-909-677-11-16 + + + + chernatkin + Sergey Chernatkin + s.chernatkin@hh.ru + hh.ru + http://hh.ru + + all + + +3 + + + igaranina + Irina Garanina + i.garanina@hh.ru + hh.ru + http://hh.ru + + all + + +3 + + + + + + junit + junit + 4.12 + test + + + com.google.code.gson + gson + 2.6.2 + test + + + commons-codec + commons-codec + 1.10 + compile + true + + + com.ning + async-http-client + 1.9.38 + provided + + + + + + + org.apache.felix + maven-bundle-plugin + 3.0.1 + + + bundle-manifest + process-classes + + manifest + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + + + + + org.apache.maven.wagon + wagon-webdav + 1.0-beta-2 + + + + + maven-compiler-plugin + 3.5.1 + + UTF-8 + 1.7 + 1.7 + true + + + + maven-deploy-plugin + 2.8.2 + + + default-deploy + deploy + + deploy + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.7 + + UTF-8 + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + UTF-8 + + + + attach-javadoc + + jar + + + + + + + + + + + release-sign-artifacts + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + diff --git a/scribejava-apis/pom.xml b/scribejava-apis/pom.xml index 958bf5563..f49cdacd0 100644 --- a/scribejava-apis/pom.xml +++ b/scribejava-apis/pom.xml @@ -1,37 +1,37 @@ - - - 4.0.0 - - - com.github.scribejava - scribejava - 2.5.4-SNAPSHOT - ../pom.xml - - - com.github.scribejava - scribejava-apis - ScribeJava APIs - jar - - - - com.github.scribejava - scribejava-core - ${project.version} - - - - - - - org.apache.felix - maven-bundle-plugin - - - org.apache.maven.plugins - maven-jar-plugin - - - - + + + 4.0.0 + + + com.github.scribejava + scribejava + 2.5.6-SNAPSHOT + ../pom.xml + + + com.github.scribejava + scribejava-apis + ScribeJava APIs + jar + + + + com.github.scribejava + scribejava-core + ${project.version} + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/OschinaApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/OschinaApi.java new file mode 100644 index 000000000..1e7eccc08 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/OschinaApi.java @@ -0,0 +1,69 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.apis.service.OsChinaOAuthServiceImpl; +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.extractors.OAuth2AccessTokenExtractor; +import com.github.scribejava.core.extractors.TokenExtractor; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import com.github.scribejava.core.utils.OAuthEncoder; +import com.github.scribejava.core.utils.Preconditions; + +public class OschinaApi extends DefaultApi20 { + + private static final String AUTHORIZE_URL = "http://www.oschina.net/action/oauth2/authorize?client_id=%s&redirect_uri=%s"; + + protected OschinaApi() { + } + + private static class InstanceHolder { + private static final OschinaApi INSTANCE = new OschinaApi(); + } + + public static OschinaApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public Verb getAccessTokenVerb() { + return Verb.GET; + } + + @Override + public String getAccessTokenEndpoint() { + return "http://www.oschina.net/action/openapi/token"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) { + Preconditions.checkValidUrl(config.getCallback(), + "Must provide a valid url as callback. GitHub does not support OOB"); + final StringBuilder sb = new StringBuilder(String.format(AUTHORIZE_URL, config.getApiKey(), + OAuthEncoder.encode(config.getCallback()))); + if (config.hasScope()) { + sb.append('&').append(OAuthConstants.SCOPE).append('=').append(OAuthEncoder.encode(config.getScope())); + } + final String state = config.getState(); + if (state != null) { + sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); + } + final String response_type = config.getResponseType(); + if (response_type != null) { + sb.append('&').append("response_type").append('=').append(OAuthEncoder.encode(response_type)); + } + return sb.toString(); + } + + @Override + public TokenExtractor getAccessTokenExtractor() { + return OAuth2AccessTokenExtractor.instance(); + } + + @Override + public OAuth20Service createService(OAuthConfig config) { + return new OsChinaOAuthServiceImpl(this, config); + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OsChinaOAuthServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OsChinaOAuthServiceImpl.java new file mode 100644 index 000000000..f21e9d192 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OsChinaOAuthServiceImpl.java @@ -0,0 +1,26 @@ +package com.github.scribejava.apis.service; + +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.model.AbstractRequest; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.oauth.OAuth20Service; + +public class OsChinaOAuthServiceImpl extends OAuth20Service { + + public OsChinaOAuthServiceImpl(DefaultApi20 api, OAuthConfig config) { + super(api, config); + } + + @Override + protected T createAccessTokenRequest(String code, T request) { + super.createAccessTokenRequest(code, request); + if (!getConfig().hasGrantType()) { + request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.AUTHORIZATION_CODE); + } + request.addParameter("dataType", "json"); + return request; + } + + +} diff --git a/scribejava-core/pom.xml b/scribejava-core/pom.xml index 50f5e9fc0..b0ec61af0 100644 --- a/scribejava-core/pom.xml +++ b/scribejava-core/pom.xml @@ -1,29 +1,29 @@ - - - 4.0.0 - - - com.github.scribejava - scribejava - 2.5.4-SNAPSHOT - ../pom.xml - - - com.github.scribejava - scribejava-core - ScribeJava Core - jar - - - - - org.apache.felix - maven-bundle-plugin - - - org.apache.maven.plugins - maven-jar-plugin - - - - + + + 4.0.0 + + + com.github.scribejava + scribejava + 2.5.6-SNAPSHOT + ../pom.xml + + + com.github.scribejava + scribejava-core + ScribeJava Core + jar + + + + + org.apache.felix + maven-bundle-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth20Service.java b/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth20Service.java index 2c7f8306b..005e3ddbc 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth20Service.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth20Service.java @@ -1,239 +1,261 @@ -package com.github.scribejava.core.oauth; - -import com.github.scribejava.core.services.Base64Encoder; -import com.ning.http.client.ProxyServer; -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.concurrent.Future; -import com.github.scribejava.core.builder.api.DefaultApi20; -import com.github.scribejava.core.model.AbstractRequest; -import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuth2Authorization; -import com.github.scribejava.core.model.OAuthAsyncRequestCallback; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.OAuthRequest; -import com.github.scribejava.core.model.OAuthRequestAsync; -import java.util.Map; - -public class OAuth20Service extends OAuthService { - - private static final String VERSION = "2.0"; - private final DefaultApi20 api; - - /** - * Default constructor - * - * @param api OAuth2.0 api information - * @param config OAuth 2.0 configuration param object - */ - public OAuth20Service(DefaultApi20 api, OAuthConfig config) { - super(config); - this.api = api; - } - - //sync version, protected to facilitate mocking - protected OAuth2AccessToken sendAccessTokenRequestSync(OAuthRequest request) { - return api.getAccessTokenExtractor().extract(request.send().getBody()); - } - - //async version, protected to facilitate mocking - protected Future sendAccessTokenRequestAsync(OAuthRequestAsync request, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - - return request.sendAsync(callback, new OAuthRequestAsync.ResponseConverter() { - @Override - public OAuth2AccessToken convert(com.ning.http.client.Response response) throws IOException { - return getApi().getAccessTokenExtractor() - .extract(OAuthRequestAsync.RESPONSE_CONVERTER.convert(response).getBody()); - } - }, proxyServer); - } - - public final OAuth2AccessToken getAccessToken(String code) { - final OAuthRequest request = createAccessTokenRequest(code, - new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestSync(request); - } - - /** - * Start the request to retrieve the access token. The optionally provided callback will be called with the Token - * when it is available. - * - * @param code code - * @param callback optional callback - * @return Future - */ - public final Future getAccessTokenAsync(String code, - OAuthAsyncRequestCallback callback) { - return getAccessTokenAsync(code, callback, null); - } - - public final Future getAccessTokenAsync(String code, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - final OAuthRequestAsync request = createAccessTokenRequest(code, - new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestAsync(request, callback, proxyServer); - } - - protected T createAccessTokenRequest(String code, T request) { - final OAuthConfig config = getConfig(); - request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); - request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); - request.addParameter(OAuthConstants.CODE, code); - request.addParameter(OAuthConstants.REDIRECT_URI, config.getCallback()); - if (config.hasScope()) { - request.addParameter(OAuthConstants.SCOPE, config.getScope()); - } - if (config.hasGrantType()) { - request.addParameter(OAuthConstants.GRANT_TYPE, config.getGrantType()); - } - return request; - } - - public final OAuth2AccessToken refreshAccessToken(String refreshToken) { - final OAuthRequest request = createRefreshTokenRequest(refreshToken, - new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestSync(request); - } - - public final Future refreshAccessTokenAsync(String refreshToken, - OAuthAsyncRequestCallback callback) { - return refreshAccessTokenAsync(refreshToken, callback, null); - } - - public final Future refreshAccessTokenAsync(String refreshToken, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - final OAuthRequestAsync request = createRefreshTokenRequest(refreshToken, - new OAuthRequestAsync(api.getAccessTokenVerb(), api.getRefreshTokenEndpoint(), this)); - - return sendAccessTokenRequestAsync(request, callback, proxyServer); - } - - protected T createRefreshTokenRequest(String refreshToken, T request) { - if (refreshToken == null || refreshToken.isEmpty()) { - throw new IllegalArgumentException("The refreshToken cannot be null or empty"); - } - final OAuthConfig config = getConfig(); - request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); - request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); - request.addParameter(OAuthConstants.REFRESH_TOKEN, refreshToken); - request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.REFRESH_TOKEN); - return request; - } - - /** - * Request Access Token Password Grant sync version - * - * @param uname User name - * @param password User password - * @return OAuth2AccessToken - */ - public final OAuth2AccessToken getAccessTokenPasswordGrant(String uname, String password) { - final OAuthRequest request = createAccessTokenPasswordGrantRequest(uname, password, - new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestSync(request); - } - - /** - * Request Access Token Password Grant async version - * - * @param uname User name - * @param password User password - * @param callback Optional callback - * @return Future - */ - public final Future getAccessTokenPasswordGrantAsync(String uname, String password, - OAuthAsyncRequestCallback callback) { - return getAccessTokenPasswordGrantAsync(uname, password, callback, null); - } - - public final Future getAccessTokenPasswordGrantAsync(String uname, String password, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - final OAuthRequestAsync request = createAccessTokenPasswordGrantRequest(uname, password, - new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestAsync(request, callback, proxyServer); - } - - protected T createAccessTokenPasswordGrantRequest(String username, String password, - T request) { - final OAuthConfig config = getConfig(); - request.addParameter(OAuthConstants.USERNAME, username); - request.addParameter(OAuthConstants.PASSWORD, password); - - if (config.hasScope()) { - request.addParameter(OAuthConstants.SCOPE, config.getScope()); - } - - request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.PASSWORD); - - request.addHeader(OAuthConstants.HEADER, OAuthConstants.BASIC + " " - + Base64Encoder.getInstance().encode( - String.format("%s:%s", config.getApiKey(), config.getApiSecret()).getBytes( - Charset.forName("UTF-8") - ) - ) - ); - - return request; - } - - /** - * {@inheritDoc} - */ - @Override - public String getVersion() { - return VERSION; - } - - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { - request.addQuerystringParameter(OAuthConstants.ACCESS_TOKEN, accessToken.getAccessToken()); - } - - /** - * Returns the URL where you should redirect your users to authenticate your application. - * - * @return the URL where you should redirect your users - */ - public final String getAuthorizationUrl() { - return getAuthorizationUrl(null); - } - - /** - * Returns the URL where you should redirect your users to authenticate your application. - * - * @param additionalParams any additional GET params to add to the URL - * @return the URL where you should redirect your users - */ - public String getAuthorizationUrl(Map additionalParams) { - return api.getAuthorizationUrl(getConfig(), additionalParams); - } - - public DefaultApi20 getApi() { - return api; - } - - public OAuth2Authorization extractAuthorization(String redirectLocation) { - final OAuth2Authorization authorization = new OAuth2Authorization(); - for (String param : redirectLocation.substring(redirectLocation.indexOf('?') + 1).split("&")) { - final String[] keyValue = param.split("="); - if (keyValue.length == 2) { - switch (keyValue[0]) { - case "code": - authorization.setCode(keyValue[1]); - break; - case "state": - authorization.setState(keyValue[1]); - break; - default: //just ignore any other param; - } - } - } - return authorization; - } -} +package com.github.scribejava.core.oauth; + +import com.github.scribejava.core.services.Base64Encoder; +import com.ning.http.client.ProxyServer; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.concurrent.Future; +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.model.AbstractRequest; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuth2Authorization; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.OAuthRequestAsync; +import java.util.Map; + +public class OAuth20Service extends OAuthService { + + private static final String VERSION = "2.0"; + private final DefaultApi20 api; + + /** + * Default constructor + * + * @param api + * OAuth2.0 api information + * @param config + * OAuth 2.0 configuration param object + */ + public OAuth20Service(DefaultApi20 api, OAuthConfig config) { + super(config); + this.api = api; + } + + // sync version, protected to facilitate mocking + protected OAuth2AccessToken sendAccessTokenRequestSync(OAuthRequest request) { + return api.getAccessTokenExtractor().extract(request.send().getBody()); + } + + // async version, protected to facilitate mocking + protected Future sendAccessTokenRequestAsync(OAuthRequestAsync request, + OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { + + + return request.sendAsync(callback, new OAuthRequestAsync.ResponseConverter() { + @Override + public OAuth2AccessToken convert(com.ning.http.client.Response response) throws IOException { + return getApi().getAccessTokenExtractor() + .extract(OAuthRequestAsync.RESPONSE_CONVERTER.convert(response).getBody()); + } + }, proxyServer); + } + + public final OAuth2AccessToken getAccessToken(String code) { + final OAuthRequest request = createAccessTokenRequest(code, + new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestSync(request); + } + + /** + * Start the request to retrieve the access token. The optionally provided + * callback will be called with the Token when it is available. + * + * @param code + * code + * @param callback + * optional callback + * @return Future + */ + public final Future getAccessTokenAsync(String code, + OAuthAsyncRequestCallback callback) { + return getAccessTokenAsync(code, callback, null); + } + + public final Future getAccessTokenAsync(String code, + OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { + final OAuthRequestAsync request = createAccessTokenRequest(code, + new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestAsync(request, callback, proxyServer); + } + + protected T createAccessTokenRequest(String code, T request) { + final OAuthConfig config = getConfig(); + request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); + request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); + request.addParameter(OAuthConstants.CODE, code); + request.addParameter(OAuthConstants.REDIRECT_URI, config.getCallback()); + if (config.hasScope()) { + request.addParameter(OAuthConstants.SCOPE, config.getScope()); + } + if (config.hasGrantType()) { + request.addParameter(OAuthConstants.GRANT_TYPE, config.getGrantType()); + } + + int index = request.getSanitizedUrl().indexOf("http://www.oschina.net"); + if (index > -1) { + request.addHeader("User-Agent", + "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"); + } + return request; + } + + public final OAuth2AccessToken refreshAccessToken(String refreshToken) { + final OAuthRequest request = createRefreshTokenRequest(refreshToken, + new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestSync(request); + } + + public final Future refreshAccessTokenAsync(String refreshToken, + OAuthAsyncRequestCallback callback) { + return refreshAccessTokenAsync(refreshToken, callback, null); + } + + public final Future refreshAccessTokenAsync(String refreshToken, + OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { + final OAuthRequestAsync request = createRefreshTokenRequest(refreshToken, + new OAuthRequestAsync(api.getAccessTokenVerb(), api.getRefreshTokenEndpoint(), this)); + + return sendAccessTokenRequestAsync(request, callback, proxyServer); + } + + protected T createRefreshTokenRequest(String refreshToken, T request) { + if (refreshToken == null || refreshToken.isEmpty()) { + throw new IllegalArgumentException("The refreshToken cannot be null or empty"); + } + final OAuthConfig config = getConfig(); + request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); + request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); + request.addParameter(OAuthConstants.REFRESH_TOKEN, refreshToken); + request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.REFRESH_TOKEN); + return request; + } + + /** + * Request Access Token Password Grant sync version + * + * @param uname + * User name + * @param password + * User password + * @return OAuth2AccessToken + */ + public final OAuth2AccessToken getAccessTokenPasswordGrant(String uname, String password) { + final OAuthRequest request = createAccessTokenPasswordGrantRequest(uname, password, + new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestSync(request); + } + + /** + * Request Access Token Password Grant async version + * + * @param uname + * User name + * @param password + * User password + * @param callback + * Optional callback + * @return Future + */ + public final Future getAccessTokenPasswordGrantAsync(String uname, String password, + OAuthAsyncRequestCallback callback) { + return getAccessTokenPasswordGrantAsync(uname, password, callback, null); + } + + public final Future getAccessTokenPasswordGrantAsync(String uname, String password, + OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { + final OAuthRequestAsync request = createAccessTokenPasswordGrantRequest(uname, password, + new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestAsync(request, callback, proxyServer); + } + + protected T createAccessTokenPasswordGrantRequest(String username, String password, + T request) { + final OAuthConfig config = getConfig(); + request.addParameter(OAuthConstants.USERNAME, username); + request.addParameter(OAuthConstants.PASSWORD, password); + + if (config.hasScope()) { + request.addParameter(OAuthConstants.SCOPE, config.getScope()); + } + + request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.PASSWORD); + + request.addHeader(OAuthConstants.HEADER, OAuthConstants.BASIC + " " + Base64Encoder.getInstance().encode( + String.format("%s:%s", config.getApiKey(), config.getApiSecret()).getBytes(Charset.forName("UTF-8")))); + + return request; + } + + /** + * {@inheritDoc} + */ + @Override + public String getVersion() { + return VERSION; + } + + public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { + request.addQuerystringParameter(OAuthConstants.ACCESS_TOKEN, accessToken.getAccessToken()); + } + + /** + * Returns the URL where you should redirect your users to authenticate your + * application. + * + * @return the URL where you should redirect your users + */ + public final String getAuthorizationUrl() { + return getAuthorizationUrl(null); + } + + + public final String getOauth2TokenUrl(String code) { + final OAuthRequest request = createAccessTokenRequest(code, + new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + return request.getCompleteUrl(); + + } + + /** + * Returns the URL where you should redirect your users to authenticate your + * application. + * + * @param additionalParams + * any additional GET params to add to the URL + * @return the URL where you should redirect your users + */ + public String getAuthorizationUrl(Map additionalParams) { + return api.getAuthorizationUrl(getConfig(), additionalParams); + } + + public DefaultApi20 getApi() { + return api; + } + + public OAuth2Authorization extractAuthorization(String redirectLocation) { + final OAuth2Authorization authorization = new OAuth2Authorization(); + for (String param : redirectLocation.substring(redirectLocation.indexOf('?') + 1).split("&")) { + final String[] keyValue = param.split("="); + if (keyValue.length == 2) { + switch (keyValue[0]) { + case "code": + authorization.setCode(keyValue[1]); + break; + case "state": + authorization.setState(keyValue[1]); + break; + default: // just ignore any other param; + } + } + } + return authorization; + } +} From 79423fef11402f9f83b73ae53a67bf9936a57f86 Mon Sep 17 00:00:00 2001 From: "ada.young" Date: Thu, 12 May 2016 11:05:07 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0QQ=E7=99=BB=E9=99=86?= =?UTF-8?q?=E5=92=8C=E5=BE=AE=E4=BF=A1=E7=99=BB=E9=99=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 240 ++++++++++-------- .../com/github/scribejava/apis/QQApi.java | 69 +++++ .../com/github/scribejava/apis/WeiXinApi.java | 69 +++++ .../scribejava/apis/examples/QQExample.java | 20 ++ .../apis/examples/WeiXinExample.java | 18 ++ 5 files changed, 310 insertions(+), 106 deletions(-) create mode 100644 scribejava-apis/src/main/java/com/github/scribejava/apis/QQApi.java create mode 100644 scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java create mode 100644 scribejava-apis/src/test/java/com/github/scribejava/apis/examples/QQExample.java create mode 100644 scribejava-apis/src/test/java/com/github/scribejava/apis/examples/WeiXinExample.java diff --git a/README.md b/README.md index 8f2bb934a..1389374b1 100644 --- a/README.md +++ b/README.md @@ -1,106 +1,134 @@ -# Welcome to the home of ScribeJava, the simple OAuth Java lib! - -# Why use ScribeJava? - -### Dead Simple - -Who said OAuth/OAuth2 was difficult? Configuring ScribeJava is __so easy your grandma can do it__! check it out: - -```java -OAuthService service = new ServiceBuilder() - .apiKey(YOUR_API_KEY) - .apiSecret(YOUR_API_SECRET) - .build(LinkedInApi20.instance()); -``` - -That **single line** (added newlines for readability) is the only thing you need to configure ScribeJava with LinkedIn's OAuth API for example. - -### Threadsafe - -Hit ScribeJava as hard and with many threads as you like. - -### Async - -You can use ning async http client out-of-box, just use ServiceBuilderAsync - -### Supports all major 1.0a and 2.0 OAuth APIs out-of-the-box - -* Google - -* Facebook - -* Yahoo - -* LinkedIn - -* Twitter - -* Foursquare - -* Evernote - -* Vimeo - -* Windows Live - -* Odnoklassniki - -* Mail.ru - -* LinkedIn2.0 - -* Google2.0 - -* GitHub - -* and many more! check the [examples folder](https://github.com/scribejava/scribejava/tree/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples) - -### Small and modular - -ScribeJava's code is small (about 1k LOC) and simple to understand. No smart-ass or "clever" hacks here. -You can use only 'core' or 'with apis' maven modules - -### Android-Ready - -Works out of the box with android(TM) applications. - -### Stable & bulletproof - -Good test coverage to keep you safe from harm. - -When something bad actually happens, ScribeJava's meaningful error messages will tell you exactly what went wrong, when and where. - -### Pull it from Maven Central! - -You can pull ScribeJava from the central maven repository, just add these to your __pom.xml__ file: - -```xml - - com.github.scribejava - scribejava-apis - 2.5.3 - -``` - -And in case you need just core classes (that's it, without any external API (FB, VK, GitHub, Google etc) specific code), you could pull just 'core' artifact. -```xml - - com.github.scribejava - scribejava-core - 2.5.3 - -``` - -## Getting started in less than 2 minutes - -Check the [Getting Started](https://github.com/scribejava/scribejava/wiki/getting-started) page and start rocking! Please Read the [FAQ](https://github.com/scribejava/scribejava/wiki/faq) before creating an issue :) - -Also, remember to read the [fantastic tutorial](http://akoskm.github.io/2015/07/31/twitter-sign-in-for-web-apps.html) that [@akoskm](https://twitter.com/akoskm) wrote to easily integrate a server side app with an API (twitter in this case). - -## Questions? - -Feel free to drop us an email or create issue right here on github.com - -## Forks - -If you have a useful fork that should be listed there please contact us +# Welcome to the home of ScribeJava, the simple OAuth Java lib! + +# Why use ScribeJava? + +### Dead Simple + +Who said OAuth/OAuth2 was difficult? Configuring ScribeJava is __so easy your grandma can do it__! check it out: + +```java +OAuthService service = new ServiceBuilder() + .apiKey(YOUR_API_KEY) + .apiSecret(YOUR_API_SECRET) + .build(LinkedInApi20.instance()); +``` + +That **single line** (added newlines for readability) is the only thing you need to configure ScribeJava with LinkedIn's OAuth API for example. + +### Threadsafe + +Hit ScribeJava as hard and with many threads as you like. + +### Async + +You can use ning async http client out-of-box, just use ServiceBuilderAsync + +### Supports all major 1.0a and 2.0 OAuth APIs out-of-the-box + +* Google + +* Facebook + +* Yahoo + +* LinkedIn + +* Twitter + +* Foursquare + +* Evernote + +* Vimeo + +* Windows Live + +* Odnoklassniki + +* Mail.ru + +* LinkedIn2.0 + +* Google2.0 + +* GitHub + +* and many more! check the [examples folder](https://github.com/scribejava/scribejava/tree/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples) + +### Small and modular + +ScribeJava's code is small (about 1k LOC) and simple to understand. No smart-ass or "clever" hacks here. +You can use only 'core' or 'with apis' maven modules + +### Android-Ready + +Works out of the box with android(TM) applications. + +### Stable & bulletproof + +Good test coverage to keep you safe from harm. + +When something bad actually happens, ScribeJava's meaningful error messages will tell you exactly what went wrong, when and where. + +### Pull it from Maven Central! + +You can pull ScribeJava from the central maven repository, just add these to your __pom.xml__ file: + +```xml + + com.github.scribejava + scribejava-apis + 2.5.3 + +``` + +And in case you need just core classes (that's it, without any external API (FB, VK, GitHub, Google etc) specific code), you could pull just 'core' artifact. +```xml + + com.github.scribejava + scribejava-core + 2.5.3 + +``` + +## Getting started in less than 2 minutes + +Check the [Getting Started](https://github.com/scribejava/scribejava/wiki/getting-started) page and start rocking! Please Read the [FAQ](https://github.com/scribejava/scribejava/wiki/faq) before creating an issue :) + +Also, remember to read the [fantastic tutorial](http://akoskm.github.io/2015/07/31/twitter-sign-in-for-web-apps.html) that [@akoskm](https://twitter.com/akoskm) wrote to easily integrate a server side app with an API (twitter in this case). + +## Questions? + +Feel free to drop us an email or create issue right here on github.com + +## Forks + +If you have a useful fork that should be listed there please contact us + + +## QQ登陆 + + final String apiKey = "101303927"; + final String apiSecret = "0c3ac6430d6e2f60dfb637101252417e "; + final OAuth20Service service = new ServiceBuilder().apiKey(apiKey).apiSecret(apiSecret) + .callback("http://www.yichisancun.com/qqlogin.htm").state("xxxx") + .scope("get_user_info,list_album,upload_pic,do_like").build(QQApi.instance()); + System.out.println(service.getAuthorizationUrl()) + +## 微信登陆 + + final String apiKey = "x"; + final String apiSecret = "x "; + final OAuth20Service service = new ServiceBuilder().apiKey(apiKey).apiSecret(apiSecret) + .callback("url").state("xxxx").scope("snsapi_login") + .build(WeiXinApi.instance()); + System.out.println(service.getAuthorizationUrl()); + +## 开源中国登陆 + + final OAuth20Service oschina = new ServiceBuilder().apiKey("CTJlkYcnBaZCsi4GGgUk").grantType("authorization_code") + .apiSecret("TlKrmPCKImAKEzk1ORZtdwooJKDIgXrF").callback("http://www.yichisancun.com/oschinalogin.htm") + .responseType("code").build(OschinaApi.instance()); + System.out.println(service.getAuthorizationUrl()); + + \ No newline at end of file diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/QQApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/QQApi.java new file mode 100644 index 000000000..f7f6ccaec --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/QQApi.java @@ -0,0 +1,69 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.apis.service.OsChinaOAuthServiceImpl; +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.extractors.OAuth2AccessTokenExtractor; +import com.github.scribejava.core.extractors.TokenExtractor; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import com.github.scribejava.core.utils.OAuthEncoder; +import com.github.scribejava.core.utils.Preconditions; + +public class QQApi extends DefaultApi20 { + + private static final String AUTHORIZE_URL = "https://graph.qq.com/oauth2.0/authorize?client_id=%s&redirect_uri=%s"; + + protected QQApi() { + } + + private static class InstanceHolder { + private static final QQApi INSTANCE = new QQApi(); + } + + public static QQApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public Verb getAccessTokenVerb() { + return Verb.GET; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://graph.qq.com/oauth2.0/token"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) { + Preconditions.checkValidUrl(config.getCallback(), + "Must provide a valid url as callback. GitHub does not support OOB"); + final StringBuilder sb = new StringBuilder(String.format(AUTHORIZE_URL, config.getApiKey(), + OAuthEncoder.encode(config.getCallback()))); + if (config.hasScope()) { + sb.append('&').append(OAuthConstants.SCOPE).append('=').append(OAuthEncoder.encode(config.getScope())); + } + final String state = config.getState(); + if (state != null) { + sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); + } + final String response_type = config.getResponseType(); + if (response_type != null) { + sb.append('&').append("response_type").append('=').append(OAuthEncoder.encode(response_type)); + } + return sb.toString(); + } + + @Override + public TokenExtractor getAccessTokenExtractor() { + return OAuth2AccessTokenExtractor.instance(); + } + + @Override + public OAuth20Service createService(OAuthConfig config) { + return new OsChinaOAuthServiceImpl(this, config); + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java new file mode 100644 index 000000000..04af96a9f --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java @@ -0,0 +1,69 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.apis.service.OsChinaOAuthServiceImpl; +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.extractors.OAuth2AccessTokenExtractor; +import com.github.scribejava.core.extractors.TokenExtractor; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import com.github.scribejava.core.utils.OAuthEncoder; +import com.github.scribejava.core.utils.Preconditions; + +public class WeiXinApi extends DefaultApi20 { + + private static final String AUTHORIZE_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s"; + + protected WeiXinApi() { + } + + private static class InstanceHolder { + private static final WeiXinApi INSTANCE = new WeiXinApi(); + } + + public static WeiXinApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public Verb getAccessTokenVerb() { + return Verb.GET; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://api.weixin.qq.com/sns/oauth2/access_token"; + } + + @Override + public String getAuthorizationUrl(OAuthConfig config) { + Preconditions.checkValidUrl(config.getCallback(), + "Must provide a valid url as callback. GitHub does not support OOB"); + final StringBuilder sb = new StringBuilder(String.format(AUTHORIZE_URL, config.getApiKey(), + OAuthEncoder.encode(config.getCallback()))); + if (config.hasScope()) { + sb.append('&').append(OAuthConstants.SCOPE).append('=').append(OAuthEncoder.encode(config.getScope())); + } + final String state = config.getState(); + if (state != null) { + sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); + } + final String response_type = config.getResponseType(); + if (response_type != null) { + sb.append('&').append("response_type").append('=').append(OAuthEncoder.encode(response_type)); + } + return sb.toString(); + } + + @Override + public TokenExtractor getAccessTokenExtractor() { + return OAuth2AccessTokenExtractor.instance(); + } + + @Override + public OAuth20Service createService(OAuthConfig config) { + return new OsChinaOAuthServiceImpl(this, config); + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/QQExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/QQExample.java new file mode 100644 index 000000000..9508b995e --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/QQExample.java @@ -0,0 +1,20 @@ +package com.github.scribejava.apis.examples; + +import com.github.scribejava.apis.QQApi; +import com.github.scribejava.apis.SinaWeiboApi20; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.oauth.OAuth20Service; + +public class QQExample { + + public static void main(String[] args) { + + final String apiKey = "101303927"; + final String apiSecret = "0c3ac6430d6e2f60dfb637101252417e "; + final OAuth20Service service = new ServiceBuilder().apiKey(apiKey).apiSecret(apiSecret) + .callback("http://www.yichisancun.com/qqlogin.htm").state("xxxx") + .scope("get_user_info,list_album,upload_pic,do_like").build(QQApi.instance()); + + System.out.println(service.getAuthorizationUrl()); + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/WeiXinExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/WeiXinExample.java new file mode 100644 index 000000000..01a816e00 --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/WeiXinExample.java @@ -0,0 +1,18 @@ +package com.github.scribejava.apis.examples; + +import com.github.scribejava.apis.WeiXinApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.oauth.OAuth20Service; + +public class WeiXinExample { + + public static void main(String[] args) { + + final String apiKey = "x"; + final String apiSecret = "x "; + final OAuth20Service service = new ServiceBuilder().apiKey(apiKey).apiSecret(apiSecret) + .callback("url").state("xxxx").scope("snsapi_login") + .build(WeiXinApi.instance()); + System.out.println(service.getAuthorizationUrl()); + } +} From 53525c94ea23640f48647abf63a1de2cafd2d519 Mon Sep 17 00:00:00 2001 From: "ada.young" Date: Fri, 17 Jun 2016 14:57:18 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=B8=BB=E5=B7=A5?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 28 +- .../github/scribejava/apis/OschinaApi.java | 44 +- .../com/github/scribejava/apis/QQApi.java | 44 +- .../com/github/scribejava/apis/WeiXinApi.java | 25 +- .../apis/service/OsChinaOAuthServiceImpl.java | 6 +- .../apis/examples/OsChinaExample.java | 18 + scribejava-core/pom.xml | 2 +- .../ahc/OAuthAsyncCompletionHandler.java | 94 +-- .../ning/OAuthAsyncCompletionHandler.java | 104 ++-- .../core/builder/ServiceBuilder.java | 380 +++++------ .../core/builder/api/DefaultApi20.java | 186 +++--- .../core/model/AbstractRequest.java | 588 +++++++++--------- .../scribejava/core/model/OAuthConfig.java | 236 +++---- .../scribejava/core/model/OAuthConstants.java | 88 +-- .../scribejava/core/model/OAuthRequest.java | 184 +++--- .../core/model/OAuthRequestAsync.java | 72 +-- .../scribejava/core/model/ParameterList.java | 200 +++--- .../scribejava/core/model/Response.java | 246 ++++---- .../core/oauth/OAuth10aService.java | 402 ++++++------ .../scribejava/core/oauth/OAuth20Service.java | 478 +++++++------- .../scribejava/core/oauth/OAuthService.java | 346 +++++------ .../scribejava/core/utils/StreamUtils.java | 98 +-- 22 files changed, 1908 insertions(+), 1961 deletions(-) create mode 100644 scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OsChinaExample.java diff --git a/pom.xml b/pom.xml index 723b1b5e1..3413fe0d6 100644 --- a/pom.xml +++ b/pom.xml @@ -203,33 +203,7 @@ - - org.apache.maven.plugins - maven-checkstyle-plugin - 2.17 - - - com.puppycrawl.tools - checkstyle - 6.19 - - - - - validate - validate - - ${basedir}/src - checkstyle.xml - UTF-8 - true - - - check - - - - + diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/OschinaApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/OschinaApi.java index 1e7eccc08..0231e2763 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/OschinaApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/OschinaApi.java @@ -37,25 +37,25 @@ public String getAccessTokenEndpoint() { return "http://www.oschina.net/action/openapi/token"; } - @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. GitHub does not support OOB"); - final StringBuilder sb = new StringBuilder(String.format(AUTHORIZE_URL, config.getApiKey(), - OAuthEncoder.encode(config.getCallback()))); - if (config.hasScope()) { - sb.append('&').append(OAuthConstants.SCOPE).append('=').append(OAuthEncoder.encode(config.getScope())); - } - final String state = config.getState(); - if (state != null) { - sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); - } - final String response_type = config.getResponseType(); - if (response_type != null) { - sb.append('&').append("response_type").append('=').append(OAuthEncoder.encode(response_type)); - } - return sb.toString(); - } +// @Override +// public String getAuthorizationUrl(OAuthConfig config) { +// Preconditions.checkValidUrl(config.getCallback(), +// "Must provide a valid url as callback. GitHub does not support OOB"); +// final StringBuilder sb = new StringBuilder(String.format(AUTHORIZE_URL, config.getApiKey(), +// OAuthEncoder.encode(config.getCallback()))); +// if (config.hasScope()) { +// sb.append('&').append(OAuthConstants.SCOPE).append('=').append(OAuthEncoder.encode(config.getScope())); +// } +// final String state = config.getState(); +// if (state != null) { +// sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); +// } +// final String response_type = config.getResponseType(); +// if (response_type != null) { +// sb.append('&').append("response_type").append('=').append(OAuthEncoder.encode(response_type)); +// } +// return sb.toString(); +// } @Override public TokenExtractor getAccessTokenExtractor() { @@ -66,4 +66,10 @@ public TokenExtractor getAccessTokenExtractor() { public OAuth20Service createService(OAuthConfig config) { return new OsChinaOAuthServiceImpl(this, config); } + + @Override + protected String getAuthorizationBaseUrl() { + // TODO Auto-generated method stub + return "http://www.oschina.net/action/oauth2/authorize"; + } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/QQApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/QQApi.java index f7f6ccaec..7293ddae5 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/QQApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/QQApi.java @@ -37,25 +37,25 @@ public String getAccessTokenEndpoint() { return "https://graph.qq.com/oauth2.0/token"; } - @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. GitHub does not support OOB"); - final StringBuilder sb = new StringBuilder(String.format(AUTHORIZE_URL, config.getApiKey(), - OAuthEncoder.encode(config.getCallback()))); - if (config.hasScope()) { - sb.append('&').append(OAuthConstants.SCOPE).append('=').append(OAuthEncoder.encode(config.getScope())); - } - final String state = config.getState(); - if (state != null) { - sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); - } - final String response_type = config.getResponseType(); - if (response_type != null) { - sb.append('&').append("response_type").append('=').append(OAuthEncoder.encode(response_type)); - } - return sb.toString(); - } +// @Override +// public String getAuthorizationUrl(OAuthConfig config) { +// Preconditions.checkValidUrl(config.getCallback(), +// "Must provide a valid url as callback. GitHub does not support OOB"); +// final StringBuilder sb = new StringBuilder(String.format(AUTHORIZE_URL, config.getApiKey(), +// OAuthEncoder.encode(config.getCallback()))); +// if (config.hasScope()) { +// sb.append('&').append(OAuthConstants.SCOPE).append('=').append(OAuthEncoder.encode(config.getScope())); +// } +// final String state = config.getState(); +// if (state != null) { +// sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); +// } +// final String response_type = config.getResponseType(); +// if (response_type != null) { +// sb.append('&').append("response_type").append('=').append(OAuthEncoder.encode(response_type)); +// } +// return sb.toString(); +// } @Override public TokenExtractor getAccessTokenExtractor() { @@ -66,4 +66,10 @@ public TokenExtractor getAccessTokenExtractor() { public OAuth20Service createService(OAuthConfig config) { return new OsChinaOAuthServiceImpl(this, config); } + + @Override + protected String getAuthorizationBaseUrl() { + // TODO Auto-generated method stub + return "https://graph.qq.com/oauth2.0/authorize"; + } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java index 04af96a9f..bc283cb00 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java @@ -37,25 +37,6 @@ public String getAccessTokenEndpoint() { return "https://api.weixin.qq.com/sns/oauth2/access_token"; } - @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. GitHub does not support OOB"); - final StringBuilder sb = new StringBuilder(String.format(AUTHORIZE_URL, config.getApiKey(), - OAuthEncoder.encode(config.getCallback()))); - if (config.hasScope()) { - sb.append('&').append(OAuthConstants.SCOPE).append('=').append(OAuthEncoder.encode(config.getScope())); - } - final String state = config.getState(); - if (state != null) { - sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); - } - final String response_type = config.getResponseType(); - if (response_type != null) { - sb.append('&').append("response_type").append('=').append(OAuthEncoder.encode(response_type)); - } - return sb.toString(); - } @Override public TokenExtractor getAccessTokenExtractor() { @@ -66,4 +47,10 @@ public TokenExtractor getAccessTokenExtractor() { public OAuth20Service createService(OAuthConfig config) { return new OsChinaOAuthServiceImpl(this, config); } + + @Override + protected String getAuthorizationBaseUrl() { + // TODO Auto-generated method stub + return "https://graph.qq.com/oauth2.0/authorize"; + } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OsChinaOAuthServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OsChinaOAuthServiceImpl.java index f21e9d192..0391d1b5f 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OsChinaOAuthServiceImpl.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OsChinaOAuthServiceImpl.java @@ -15,9 +15,9 @@ public OsChinaOAuthServiceImpl(DefaultApi20 api, OAuthConfig config) { @Override protected T createAccessTokenRequest(String code, T request) { super.createAccessTokenRequest(code, request); - if (!getConfig().hasGrantType()) { - request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.AUTHORIZATION_CODE); - } +// if (!getConfig().hasGrantType()) { +// request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.AUTHORIZATION_CODE); +// } request.addParameter("dataType", "json"); return request; } diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OsChinaExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OsChinaExample.java new file mode 100644 index 000000000..e46dffb5c --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OsChinaExample.java @@ -0,0 +1,18 @@ +package com.github.scribejava.apis.examples; + +import com.github.scribejava.apis.OschinaApi; +import com.github.scribejava.apis.QQApi; +import com.github.scribejava.apis.SinaWeiboApi20; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.oauth.OAuth20Service; + +public class OsChinaExample { + + public static void main(String[] args) { + + final OAuth20Service oschina = new ServiceBuilder().apiKey("CTJlkYcnBaZCsi4GGgUk") + .apiSecret("TlKrmPCKImAKEzk1ORZtdwooJKDIgXrF").callback("http://www.yichisancun.com/oschinalogin.htm") + .responseType("code").build(OschinaApi.instance()); + System.out.println(oschina.getAuthorizationUrl()); + } +} diff --git a/scribejava-core/pom.xml b/scribejava-core/pom.xml index bd772955b..50e937547 100644 --- a/scribejava-core/pom.xml +++ b/scribejava-core/pom.xml @@ -5,7 +5,7 @@ com.github.scribejava scribejava - 2.5.6-SNAPSHOT + 2.7.4-SNAPSHOT ../pom.xml diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/async/ahc/OAuthAsyncCompletionHandler.java b/scribejava-core/src/main/java/com/github/scribejava/core/async/ahc/OAuthAsyncCompletionHandler.java index b556fb6ad..2c778ac94 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/async/ahc/OAuthAsyncCompletionHandler.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/async/ahc/OAuthAsyncCompletionHandler.java @@ -1,47 +1,47 @@ -package com.github.scribejava.core.async.ahc; - -import com.github.scribejava.core.model.OAuthAsyncRequestCallback; -import com.github.scribejava.core.model.OAuthRequestAsync; -import com.github.scribejava.core.model.Response; -import io.netty.handler.codec.http.HttpHeaders; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import org.asynchttpclient.AsyncCompletionHandler; - -public class OAuthAsyncCompletionHandler extends AsyncCompletionHandler { - - private final OAuthAsyncRequestCallback callback; - private final OAuthRequestAsync.ResponseConverter converter; - - public OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback callback, - OAuthRequestAsync.ResponseConverter converter) { - this.callback = callback; - this.converter = converter; - } - - @Override - public T onCompleted(org.asynchttpclient.Response ahcResponse) throws IOException { - final HttpHeaders map = ahcResponse.getHeaders(); - final Map headersMap = new HashMap<>(); - for (Map.Entry header : map) { - headersMap.put(header.getKey(), header.getValue()); - } - final Response response = new Response(ahcResponse.getStatusCode(), ahcResponse.getStatusText(), headersMap, - ahcResponse.getResponseBody(), ahcResponse.getResponseBodyAsStream()); - - @SuppressWarnings("unchecked") - final T t = converter == null ? (T) response : converter.convert(response); - if (callback != null) { - callback.onCompleted(t); - } - return t; - } - - @Override - public void onThrowable(Throwable t) { - if (callback != null) { - callback.onThrowable(t); - } - } -}; +package com.github.scribejava.core.async.ahc; + +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthRequestAsync; +import com.github.scribejava.core.model.Response; +import io.netty.handler.codec.http.HttpHeaders; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.asynchttpclient.AsyncCompletionHandler; + +public class OAuthAsyncCompletionHandler extends AsyncCompletionHandler { + + private final OAuthAsyncRequestCallback callback; + private final OAuthRequestAsync.ResponseConverter converter; + + public OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback callback, + OAuthRequestAsync.ResponseConverter converter) { + this.callback = callback; + this.converter = converter; + } + + @Override + public T onCompleted(org.asynchttpclient.Response ahcResponse) throws IOException { + final HttpHeaders map = ahcResponse.getHeaders(); + final Map headersMap = new HashMap<>(); + for (Map.Entry header : map) { + headersMap.put(header.getKey(), header.getValue()); + } + final Response response = new Response(ahcResponse.getStatusCode(), ahcResponse.getStatusText(), headersMap, + ahcResponse.getResponseBody(), ahcResponse.getResponseBodyAsStream()); + + @SuppressWarnings("unchecked") + final T t = converter == null ? (T) response : converter.convert(response); + if (callback != null) { + callback.onCompleted(t); + } + return t; + } + + @Override + public void onThrowable(Throwable t) { + if (callback != null) { + callback.onThrowable(t); + } + } +}; diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/async/ning/OAuthAsyncCompletionHandler.java b/scribejava-core/src/main/java/com/github/scribejava/core/async/ning/OAuthAsyncCompletionHandler.java index adbcf10bb..20abd802d 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/async/ning/OAuthAsyncCompletionHandler.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/async/ning/OAuthAsyncCompletionHandler.java @@ -1,52 +1,52 @@ -package com.github.scribejava.core.async.ning; - -import com.github.scribejava.core.model.OAuthAsyncRequestCallback; -import com.github.scribejava.core.model.OAuthRequestAsync; -import com.github.scribejava.core.model.Response; -import com.ning.http.client.AsyncCompletionHandler; -import com.ning.http.client.FluentCaseInsensitiveStringsMap; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class OAuthAsyncCompletionHandler extends AsyncCompletionHandler { - - private final OAuthAsyncRequestCallback callback; - private final OAuthRequestAsync.ResponseConverter converter; - - public OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback callback, - OAuthRequestAsync.ResponseConverter converter) { - this.callback = callback; - this.converter = converter; - } - - @Override - public T onCompleted(com.ning.http.client.Response ningResponse) throws IOException { - final FluentCaseInsensitiveStringsMap map = ningResponse.getHeaders(); - final Map headersMap = new HashMap<>(); - for (FluentCaseInsensitiveStringsMap.Entry> header : map) { - final StringBuilder value = new StringBuilder(); - for (String str : header.getValue()) { - value.append(str); - } - headersMap.put(header.getKey(), value.toString()); - } - final Response response = new Response(ningResponse.getStatusCode(), ningResponse.getStatusText(), headersMap, - ningResponse.getResponseBody(), ningResponse.getResponseBodyAsStream()); - - @SuppressWarnings("unchecked") - final T t = converter == null ? (T) response : converter.convert(response); - if (callback != null) { - callback.onCompleted(t); - } - return t; - } - - @Override - public void onThrowable(Throwable t) { - if (callback != null) { - callback.onThrowable(t); - } - } -}; +package com.github.scribejava.core.async.ning; + +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthRequestAsync; +import com.github.scribejava.core.model.Response; +import com.ning.http.client.AsyncCompletionHandler; +import com.ning.http.client.FluentCaseInsensitiveStringsMap; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OAuthAsyncCompletionHandler extends AsyncCompletionHandler { + + private final OAuthAsyncRequestCallback callback; + private final OAuthRequestAsync.ResponseConverter converter; + + public OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback callback, + OAuthRequestAsync.ResponseConverter converter) { + this.callback = callback; + this.converter = converter; + } + + @Override + public T onCompleted(com.ning.http.client.Response ningResponse) throws IOException { + final FluentCaseInsensitiveStringsMap map = ningResponse.getHeaders(); + final Map headersMap = new HashMap<>(); + for (FluentCaseInsensitiveStringsMap.Entry> header : map) { + final StringBuilder value = new StringBuilder(); + for (String str : header.getValue()) { + value.append(str); + } + headersMap.put(header.getKey(), value.toString()); + } + final Response response = new Response(ningResponse.getStatusCode(), ningResponse.getStatusText(), headersMap, + ningResponse.getResponseBody(), ningResponse.getResponseBodyAsStream()); + + @SuppressWarnings("unchecked") + final T t = converter == null ? (T) response : converter.convert(response); + if (callback != null) { + callback.onCompleted(t); + } + return t; + } + + @Override + public void onThrowable(Throwable t) { + if (callback != null) { + callback.onThrowable(t); + } + } +}; diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/builder/ServiceBuilder.java b/scribejava-core/src/main/java/com/github/scribejava/core/builder/ServiceBuilder.java index 12195ab56..5bd19e3af 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/builder/ServiceBuilder.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/builder/ServiceBuilder.java @@ -1,190 +1,190 @@ -package com.github.scribejava.core.builder; - -import com.github.scribejava.core.builder.api.BaseApi; -import com.github.scribejava.core.model.OAuthConfig; -import java.io.OutputStream; -import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.SignatureType; -import com.github.scribejava.core.oauth.OAuthService; -import com.github.scribejava.core.utils.Preconditions; - -/** - * Implementation of the Builder pattern, with a fluent interface that creates a {@link OAuthService} - */ -public class ServiceBuilder { - - private String callback; - private String apiKey; - private String apiSecret; - private String scope; - private String state; - private SignatureType signatureType; - private OutputStream debugStream; - private String responseType = "code"; - private String userAgent; - - //sync version only - private Integer connectTimeout; - private Integer readTimeout; - - //async version only - //ning 1.9 - private com.ning.http.client.AsyncHttpClientConfig ningAsyncHttpClientConfig; - private String ningAsyncHttpProviderClassName; - //AHC 2.0 - private org.asynchttpclient.AsyncHttpClientConfig ahcAsyncHttpClientConfig; - - public ServiceBuilder() { - callback = OAuthConstants.OUT_OF_BAND; - signatureType = SignatureType.Header; - } - - /** - * Adds an OAuth callback url - * - * @param callback callback url. Must be a valid url or 'oob' for out of band OAuth - * @return the {@link ServiceBuilder} instance for method chaining - */ - public ServiceBuilder callback(String callback) { - Preconditions.checkNotNull(callback, "Callback can't be null"); - this.callback = callback; - return this; - } - - /** - * Configures the api key - * - * @param apiKey The api key for your application - * @return the {@link ServiceBuilder} instance for method chaining - */ - public ServiceBuilder apiKey(String apiKey) { - Preconditions.checkEmptyString(apiKey, "Invalid Api key"); - this.apiKey = apiKey; - return this; - } - - /** - * Configures the api secret - * - * @param apiSecret The api secret for your application - * @return the {@link ServiceBuilder} instance for method chaining - */ - public ServiceBuilder apiSecret(String apiSecret) { - Preconditions.checkEmptyString(apiSecret, "Invalid Api secret"); - this.apiSecret = apiSecret; - return this; - } - - /** - * Configures the OAuth scope. This is only necessary in some APIs (like Google's). - * - * @param scope The OAuth scope - * @return the {@link ServiceBuilder} instance for method chaining - */ - public ServiceBuilder scope(String scope) { - Preconditions.checkEmptyString(scope, "Invalid OAuth scope"); - this.scope = scope; - return this; - } - - /** - * Configures the anti forgery session state. This is available in some APIs (like Google's). - * - * @param state The OAuth state - * @return the {@link ServiceBuilder} instance for method chaining - */ - public ServiceBuilder state(String state) { - Preconditions.checkEmptyString(state, "Invalid OAuth state"); - this.state = state; - return this; - } - - /** - * Configures the signature type, choose between header, querystring, etc. Defaults to Header - * - * @param signatureType SignatureType - * @return the {@link ServiceBuilder} instance for method chaining - */ - public ServiceBuilder signatureType(SignatureType signatureType) { - Preconditions.checkNotNull(signatureType, "Signature type can't be null"); - this.signatureType = signatureType; - return this; - } - - public ServiceBuilder debugStream(OutputStream debugStream) { - Preconditions.checkNotNull(debugStream, "debug stream can't be null"); - this.debugStream = debugStream; - return this; - } - - public ServiceBuilder responseType(String responseType) { - Preconditions.checkEmptyString(responseType, "Invalid OAuth responseType"); - this.responseType = responseType; - return this; - } - - public ServiceBuilder connectTimeout(Integer connectTimeout) { - Preconditions.checkNotNull(connectTimeout, "Connection timeout can't be null"); - this.connectTimeout = connectTimeout; - return this; - } - - public ServiceBuilder readTimeout(Integer readTimeout) { - Preconditions.checkNotNull(readTimeout, "Read timeout can't be null"); - this.readTimeout = readTimeout; - return this; - } - - public ServiceBuilder asyncNingHttpClientConfig(com.ning.http.client.AsyncHttpClientConfig asyncHttpClientConfig) { - Preconditions.checkNotNull(asyncHttpClientConfig, "asyncHttpClientConfig can't be null"); - ningAsyncHttpClientConfig = asyncHttpClientConfig; - ahcAsyncHttpClientConfig = null; - return this; - } - - public ServiceBuilder asyncNingHttpProviderClassName(String asyncHttpProviderClassName) { - this.ningAsyncHttpProviderClassName = asyncHttpProviderClassName; - ahcAsyncHttpClientConfig = null; - return this; - } - - public ServiceBuilder asyncAHCHttpClientConfig(org.asynchttpclient.AsyncHttpClientConfig asyncHttpClientConfig) { - Preconditions.checkNotNull(asyncHttpClientConfig, "asyncHttpClientConfig can't be null"); - ahcAsyncHttpClientConfig = asyncHttpClientConfig; - ningAsyncHttpClientConfig = null; - ningAsyncHttpProviderClassName = null; - return this; - } - - public ServiceBuilder userAgent(String userAgent) { - this.userAgent = userAgent; - return this; - } - - public ServiceBuilder debug() { - debugStream(System.out); - return this; - } - - public void checkPreconditions() { - Preconditions.checkEmptyString(apiKey, "You must provide an api key"); - } - - private OAuthConfig createConfig() { - checkPreconditions(); - return new OAuthConfig(apiKey, apiSecret, callback, signatureType, scope, debugStream, state, responseType, - userAgent, connectTimeout, readTimeout, ningAsyncHttpClientConfig, ningAsyncHttpProviderClassName, - ahcAsyncHttpClientConfig); - } - - /** - * Returns the fully configured {@link S} - * - * @param OAuthService implementation (OAuth1/OAuth2/any API specific) - * @param api will build Service for this API - * @return fully configured {@link S} - */ - public S build(BaseApi api) { - return api.createService(createConfig()); - } -} +package com.github.scribejava.core.builder; + +import com.github.scribejava.core.builder.api.BaseApi; +import com.github.scribejava.core.model.OAuthConfig; +import java.io.OutputStream; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.SignatureType; +import com.github.scribejava.core.oauth.OAuthService; +import com.github.scribejava.core.utils.Preconditions; + +/** + * Implementation of the Builder pattern, with a fluent interface that creates a {@link OAuthService} + */ +public class ServiceBuilder { + + private String callback; + private String apiKey; + private String apiSecret; + private String scope; + private String state; + private SignatureType signatureType; + private OutputStream debugStream; + private String responseType = "code"; + private String userAgent; + + //sync version only + private Integer connectTimeout; + private Integer readTimeout; + + //async version only + //ning 1.9 + private com.ning.http.client.AsyncHttpClientConfig ningAsyncHttpClientConfig; + private String ningAsyncHttpProviderClassName; + //AHC 2.0 + private org.asynchttpclient.AsyncHttpClientConfig ahcAsyncHttpClientConfig; + + public ServiceBuilder() { + callback = OAuthConstants.OUT_OF_BAND; + signatureType = SignatureType.Header; + } + + /** + * Adds an OAuth callback url + * + * @param callback callback url. Must be a valid url or 'oob' for out of band OAuth + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder callback(String callback) { + Preconditions.checkNotNull(callback, "Callback can't be null"); + this.callback = callback; + return this; + } + + /** + * Configures the api key + * + * @param apiKey The api key for your application + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder apiKey(String apiKey) { + Preconditions.checkEmptyString(apiKey, "Invalid Api key"); + this.apiKey = apiKey; + return this; + } + + /** + * Configures the api secret + * + * @param apiSecret The api secret for your application + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder apiSecret(String apiSecret) { + Preconditions.checkEmptyString(apiSecret, "Invalid Api secret"); + this.apiSecret = apiSecret; + return this; + } + + /** + * Configures the OAuth scope. This is only necessary in some APIs (like Google's). + * + * @param scope The OAuth scope + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder scope(String scope) { + Preconditions.checkEmptyString(scope, "Invalid OAuth scope"); + this.scope = scope; + return this; + } + + /** + * Configures the anti forgery session state. This is available in some APIs (like Google's). + * + * @param state The OAuth state + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder state(String state) { + Preconditions.checkEmptyString(state, "Invalid OAuth state"); + this.state = state; + return this; + } + + /** + * Configures the signature type, choose between header, querystring, etc. Defaults to Header + * + * @param signatureType SignatureType + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder signatureType(SignatureType signatureType) { + Preconditions.checkNotNull(signatureType, "Signature type can't be null"); + this.signatureType = signatureType; + return this; + } + + public ServiceBuilder debugStream(OutputStream debugStream) { + Preconditions.checkNotNull(debugStream, "debug stream can't be null"); + this.debugStream = debugStream; + return this; + } + + public ServiceBuilder responseType(String responseType) { + Preconditions.checkEmptyString(responseType, "Invalid OAuth responseType"); + this.responseType = responseType; + return this; + } + + public ServiceBuilder connectTimeout(Integer connectTimeout) { + Preconditions.checkNotNull(connectTimeout, "Connection timeout can't be null"); + this.connectTimeout = connectTimeout; + return this; + } + + public ServiceBuilder readTimeout(Integer readTimeout) { + Preconditions.checkNotNull(readTimeout, "Read timeout can't be null"); + this.readTimeout = readTimeout; + return this; + } + + public ServiceBuilder asyncNingHttpClientConfig(com.ning.http.client.AsyncHttpClientConfig asyncHttpClientConfig) { + Preconditions.checkNotNull(asyncHttpClientConfig, "asyncHttpClientConfig can't be null"); + ningAsyncHttpClientConfig = asyncHttpClientConfig; + ahcAsyncHttpClientConfig = null; + return this; + } + + public ServiceBuilder asyncNingHttpProviderClassName(String asyncHttpProviderClassName) { + this.ningAsyncHttpProviderClassName = asyncHttpProviderClassName; + ahcAsyncHttpClientConfig = null; + return this; + } + + public ServiceBuilder asyncAHCHttpClientConfig(org.asynchttpclient.AsyncHttpClientConfig asyncHttpClientConfig) { + Preconditions.checkNotNull(asyncHttpClientConfig, "asyncHttpClientConfig can't be null"); + ahcAsyncHttpClientConfig = asyncHttpClientConfig; + ningAsyncHttpClientConfig = null; + ningAsyncHttpProviderClassName = null; + return this; + } + + public ServiceBuilder userAgent(String userAgent) { + this.userAgent = userAgent; + return this; + } + + public ServiceBuilder debug() { + debugStream(System.out); + return this; + } + + public void checkPreconditions() { + Preconditions.checkEmptyString(apiKey, "You must provide an api key"); + } + + private OAuthConfig createConfig() { + checkPreconditions(); + return new OAuthConfig(apiKey, apiSecret, callback, signatureType, scope, debugStream, state, responseType, + userAgent, connectTimeout, readTimeout, ningAsyncHttpClientConfig, ningAsyncHttpProviderClassName, + ahcAsyncHttpClientConfig); + } + + /** + * Returns the fully configured {@link S} + * + * @param OAuthService implementation (OAuth1/OAuth2/any API specific) + * @param api will build Service for this API + * @return fully configured {@link S} + */ + public S build(BaseApi api) { + return api.createService(createConfig()); + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/DefaultApi20.java b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/DefaultApi20.java index 480a7a34d..9f10b4350 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/DefaultApi20.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/DefaultApi20.java @@ -1,93 +1,93 @@ -package com.github.scribejava.core.builder.api; - -import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; -import com.github.scribejava.core.extractors.TokenExtractor; -import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.ParameterList; -import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.oauth.OAuth20Service; -import java.util.Map; - -/** - * Default implementation of the OAuth protocol, version 2.0 - * - * This class is meant to be extended by concrete implementations of the API, providing the endpoints and - * endpoint-http-verbs. - * - * If your API adheres to the 2.0 protocol correctly, you just need to extend this class and define the getters for your - * endpoints. - * - * If your API does something a bit different, you can override the different extractors or services, in order to - * fine-tune the process. Please read the javadocs of the interfaces to get an idea of what to do. - * - */ -public abstract class DefaultApi20 implements BaseApi { - - /** - * Returns the access token extractor. - * - * @return access token extractor - */ - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); - } - - /** - * Returns the verb for the access token endpoint (defaults to POST) - * - * @return access token endpoint verb - */ - public Verb getAccessTokenVerb() { - return Verb.POST; - } - - /** - * Returns the URL that receives the access token requests. - * - * @return access token URL - */ - public abstract String getAccessTokenEndpoint(); - - public String getRefreshTokenEndpoint() { - return getAccessTokenEndpoint(); - } - - protected abstract String getAuthorizationBaseUrl(); - - /** - * Returns the URL where you should redirect your users to authenticate your application. - * - * @param config OAuth 2.0 configuration param object - * @param additionalParams any additional GET params to add to the URL - * @return the URL where you should redirect your users - */ - public String getAuthorizationUrl(OAuthConfig config, Map additionalParams) { - final ParameterList parameters = new ParameterList(additionalParams); - parameters.add(OAuthConstants.RESPONSE_TYPE, config.getResponseType()); - parameters.add(OAuthConstants.CLIENT_ID, config.getApiKey()); - - final String callback = config.getCallback(); - if (callback != null) { - parameters.add(OAuthConstants.REDIRECT_URI, callback); - } - - final String scope = config.getScope(); - if (scope != null) { - parameters.add(OAuthConstants.SCOPE, scope); - } - - final String state = config.getState(); - if (state != null) { - parameters.add(OAuthConstants.STATE, state); - } - - return parameters.appendTo(getAuthorizationBaseUrl()); - } - - @Override - public OAuth20Service createService(OAuthConfig config) { - return new OAuth20Service(this, config); - } -} +package com.github.scribejava.core.builder.api; + +import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; +import com.github.scribejava.core.extractors.TokenExtractor; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.ParameterList; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import java.util.Map; + +/** + * Default implementation of the OAuth protocol, version 2.0 + * + * This class is meant to be extended by concrete implementations of the API, providing the endpoints and + * endpoint-http-verbs. + * + * If your API adheres to the 2.0 protocol correctly, you just need to extend this class and define the getters for your + * endpoints. + * + * If your API does something a bit different, you can override the different extractors or services, in order to + * fine-tune the process. Please read the javadocs of the interfaces to get an idea of what to do. + * + */ +public abstract class DefaultApi20 implements BaseApi { + + /** + * Returns the access token extractor. + * + * @return access token extractor + */ + public TokenExtractor getAccessTokenExtractor() { + return OAuth2AccessTokenJsonExtractor.instance(); + } + + /** + * Returns the verb for the access token endpoint (defaults to POST) + * + * @return access token endpoint verb + */ + public Verb getAccessTokenVerb() { + return Verb.POST; + } + + /** + * Returns the URL that receives the access token requests. + * + * @return access token URL + */ + public abstract String getAccessTokenEndpoint(); + + public String getRefreshTokenEndpoint() { + return getAccessTokenEndpoint(); + } + + protected abstract String getAuthorizationBaseUrl(); + + /** + * Returns the URL where you should redirect your users to authenticate your application. + * + * @param config OAuth 2.0 configuration param object + * @param additionalParams any additional GET params to add to the URL + * @return the URL where you should redirect your users + */ + public String getAuthorizationUrl(OAuthConfig config, Map additionalParams) { + final ParameterList parameters = new ParameterList(additionalParams); + parameters.add(OAuthConstants.RESPONSE_TYPE, config.getResponseType()); + parameters.add(OAuthConstants.CLIENT_ID, config.getApiKey()); + + final String callback = config.getCallback(); + if (callback != null) { + parameters.add(OAuthConstants.REDIRECT_URI, callback); + } + + final String scope = config.getScope(); + if (scope != null) { + parameters.add(OAuthConstants.SCOPE, scope); + } + + final String state = config.getState(); + if (state != null) { + parameters.add(OAuthConstants.STATE, state); + } + + return parameters.appendTo(getAuthorizationBaseUrl()); + } + + @Override + public OAuth20Service createService(OAuthConfig config) { + return new OAuth20Service(this, config); + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/AbstractRequest.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/AbstractRequest.java index 4db6ccec7..0ab0c3361 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/AbstractRequest.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/AbstractRequest.java @@ -1,294 +1,294 @@ -package com.github.scribejava.core.model; - -import java.io.UnsupportedEncodingException; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.Map; -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.oauth.OAuthService; - -/** - * The representation of an OAuth HttpRequest. - */ -public abstract class AbstractRequest { - - public static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded"; - public static final String CONTENT_TYPE = "Content-Type"; - protected static final String CONTENT_LENGTH = "Content-Length"; - private static final String OAUTH_PREFIX = "oauth_"; - - private final String url; - private final Verb verb; - private final ParameterList querystringParams = new ParameterList(); - private final ParameterList bodyParams = new ParameterList(); - private final Map headers = new HashMap<>(); - private boolean connectionKeepAlive; - private boolean followRedirects = true; - private final OAuthService service; - - private String payload; - private String charset; - private byte[] bytePayload; - private final Map oauthParameters = new HashMap<>(); - - private String realm; - - /** - * Default constructor. - * - * @param verb Http verb/method - * @param url resource URL - * @param service OAuthService - */ - public AbstractRequest(Verb verb, String url, OAuthService service) { - this.verb = verb; - this.url = url; - this.service = service; - } - - /** - * Adds an OAuth parameter. - * - * @param key name of the parameter - * @param value value of the parameter - * @throws IllegalArgumentException if the parameter is not an OAuth parameter - */ - public void addOAuthParameter(String key, String value) { - oauthParameters.put(checkKey(key), value); - } - - private String checkKey(String key) { - if (key.startsWith(OAUTH_PREFIX) || key.equals(OAuthConstants.SCOPE) || key.equals(OAuthConstants.REALM)) { - return key; - } else { - throw new IllegalArgumentException( - String.format("OAuth parameters must either be '%s', '%s' or start with '%s'", OAuthConstants.SCOPE, - OAuthConstants.REALM, OAUTH_PREFIX)); - } - } - - public Map getOauthParameters() { - return oauthParameters; - } - - public void setRealm(String realm) { - this.realm = realm; - } - - public String getRealm() { - return realm; - } - - /** - * Returns the complete url (host + resource + encoded querystring parameters). - * - * @return the complete url. - */ - public String getCompleteUrl() { - return querystringParams.appendTo(url); - } - - /** - * Add an HTTP Header to the Request - * - * @param key the header name - * @param value the header value - */ - public void addHeader(String key, String value) { - this.headers.put(key, value); - } - - /** - * Add a body Parameter (for POST/ PUT Requests) - * - * @param key the parameter name - * @param value the parameter value - */ - public void addBodyParameter(String key, String value) { - this.bodyParams.add(key, value); - } - - /** - * Add a QueryString parameter - * - * @param key the parameter name - * @param value the parameter value - */ - public void addQuerystringParameter(String key, String value) { - this.querystringParams.add(key, value); - } - - public void addParameter(String key, String value) { - if (hasBodyContent()) { - bodyParams.add(key, value); - } else { - querystringParams.add(key, value); - } - } - - protected boolean hasBodyContent() { - return verb == Verb.PUT || verb == Verb.POST; - } - - /** - * Add body payload. This method is used when the HTTP body is not a form-url-encoded string, but another thing. - * Like for example XML. Note: The contents are not part of the OAuth signature - * - * @param payload the body of the request - */ - public void addPayload(String payload) { - this.payload = payload; - } - - /** - * Overloaded version for byte arrays - * - * @param payload byte[] - */ - public void addPayload(byte[] payload) { - this.bytePayload = payload.clone(); - } - - /** - * Get a {@link ParameterList} with the query string parameters. - * - * @return a {@link ParameterList} containing the query string parameters. - * @throws OAuthException if the request URL is not valid. - */ - public ParameterList getQueryStringParams() { - try { - final ParameterList result = new ParameterList(); - final 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() { - return bodyParams; - } - - /** - * Obtains the URL of the HTTP Request. - * - * @return the original URL of the HTTP Request - */ - public String getUrl() { - return url; - } - - /** - * Returns the URL without the port and the query string part. - * - * @return the OAuth-sanitized URL - */ - public String getSanitizedUrl() { - if (url.startsWith("http://") && (url.endsWith(":80") || url.contains(":80/"))) { - return url.replaceAll("\\?.*", "").replaceAll(":80", ""); - } else if (url.startsWith("https://") && (url.endsWith(":443") || url.contains(":443/"))) { - return url.replaceAll("\\?.*", "").replaceAll(":443", ""); - } else { - return url.replaceAll("\\?.*", ""); - } - } - - /** - * 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; - } - final String body = (payload == null) ? bodyParams.asFormUrlEncodedString() : payload; - try { - return body.getBytes(getCharset()); - } catch (UnsupportedEncodingException uee) { - throw new OAuthException("Unsupported Charset: " + getCharset(), uee); - } - } - - @Override - public String toString() { - return String.format("@Request(%s %s)", getVerb(), getUrl()); - } - - public Verb getVerb() { - return verb; - } - - public Map getHeaders() { - return headers; - } - - public String getCharset() { - return charset == null ? Charset.defaultCharset().name() : charset; - } - - /** - * Set the charset of the body of the request - * - * @param charsetName name of the charset of the request - */ - public void setCharset(String charsetName) { - charset = charsetName; - } - - /** - * Sets whether the underlying Http Connection is persistent or not. - * - * @param connectionKeepAlive boolean - * - * @see http://download.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html - */ - public void setConnectionKeepAlive(boolean connectionKeepAlive) { - this.connectionKeepAlive = connectionKeepAlive; - } - - /** - * Sets whether the underlying Http Connection follows redirects or not. - * - * Defaults to true (follow redirects) - * - * @see http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html#setInstanceFollowRedirects(boolean) - * @param followRedirects boolean - */ - public void setFollowRedirects(boolean followRedirects) { - this.followRedirects = followRedirects; - } - - public boolean isConnectionKeepAlive() { - return connectionKeepAlive; - } - - public boolean isFollowRedirects() { - return followRedirects; - } - - public OAuthService getService() { - return service; - } -} +package com.github.scribejava.core.model; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; +import com.github.scribejava.core.exceptions.OAuthException; +import com.github.scribejava.core.oauth.OAuthService; + +/** + * The representation of an OAuth HttpRequest. + */ +public abstract class AbstractRequest { + + public static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded"; + public static final String CONTENT_TYPE = "Content-Type"; + protected static final String CONTENT_LENGTH = "Content-Length"; + private static final String OAUTH_PREFIX = "oauth_"; + + private final String url; + private final Verb verb; + private final ParameterList querystringParams = new ParameterList(); + private final ParameterList bodyParams = new ParameterList(); + private final Map headers = new HashMap<>(); + private boolean connectionKeepAlive; + private boolean followRedirects = true; + private final OAuthService service; + + private String payload; + private String charset; + private byte[] bytePayload; + private final Map oauthParameters = new HashMap<>(); + + private String realm; + + /** + * Default constructor. + * + * @param verb Http verb/method + * @param url resource URL + * @param service OAuthService + */ + public AbstractRequest(Verb verb, String url, OAuthService service) { + this.verb = verb; + this.url = url; + this.service = service; + } + + /** + * Adds an OAuth parameter. + * + * @param key name of the parameter + * @param value value of the parameter + * @throws IllegalArgumentException if the parameter is not an OAuth parameter + */ + public void addOAuthParameter(String key, String value) { + oauthParameters.put(checkKey(key), value); + } + + private String checkKey(String key) { + if (key.startsWith(OAUTH_PREFIX) || key.equals(OAuthConstants.SCOPE) || key.equals(OAuthConstants.REALM)) { + return key; + } else { + throw new IllegalArgumentException( + String.format("OAuth parameters must either be '%s', '%s' or start with '%s'", OAuthConstants.SCOPE, + OAuthConstants.REALM, OAUTH_PREFIX)); + } + } + + public Map getOauthParameters() { + return oauthParameters; + } + + public void setRealm(String realm) { + this.realm = realm; + } + + public String getRealm() { + return realm; + } + + /** + * Returns the complete url (host + resource + encoded querystring parameters). + * + * @return the complete url. + */ + public String getCompleteUrl() { + return querystringParams.appendTo(url); + } + + /** + * Add an HTTP Header to the Request + * + * @param key the header name + * @param value the header value + */ + public void addHeader(String key, String value) { + this.headers.put(key, value); + } + + /** + * Add a body Parameter (for POST/ PUT Requests) + * + * @param key the parameter name + * @param value the parameter value + */ + public void addBodyParameter(String key, String value) { + this.bodyParams.add(key, value); + } + + /** + * Add a QueryString parameter + * + * @param key the parameter name + * @param value the parameter value + */ + public void addQuerystringParameter(String key, String value) { + this.querystringParams.add(key, value); + } + + public void addParameter(String key, String value) { + if (hasBodyContent()) { + bodyParams.add(key, value); + } else { + querystringParams.add(key, value); + } + } + + protected boolean hasBodyContent() { + return verb == Verb.PUT || verb == Verb.POST; + } + + /** + * Add body payload. This method is used when the HTTP body is not a form-url-encoded string, but another thing. + * Like for example XML. Note: The contents are not part of the OAuth signature + * + * @param payload the body of the request + */ + public void addPayload(String payload) { + this.payload = payload; + } + + /** + * Overloaded version for byte arrays + * + * @param payload byte[] + */ + public void addPayload(byte[] payload) { + this.bytePayload = payload.clone(); + } + + /** + * Get a {@link ParameterList} with the query string parameters. + * + * @return a {@link ParameterList} containing the query string parameters. + * @throws OAuthException if the request URL is not valid. + */ + public ParameterList getQueryStringParams() { + try { + final ParameterList result = new ParameterList(); + final 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() { + return bodyParams; + } + + /** + * Obtains the URL of the HTTP Request. + * + * @return the original URL of the HTTP Request + */ + public String getUrl() { + return url; + } + + /** + * Returns the URL without the port and the query string part. + * + * @return the OAuth-sanitized URL + */ + public String getSanitizedUrl() { + if (url.startsWith("http://") && (url.endsWith(":80") || url.contains(":80/"))) { + return url.replaceAll("\\?.*", "").replaceAll(":80", ""); + } else if (url.startsWith("https://") && (url.endsWith(":443") || url.contains(":443/"))) { + return url.replaceAll("\\?.*", "").replaceAll(":443", ""); + } else { + return url.replaceAll("\\?.*", ""); + } + } + + /** + * 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; + } + final String body = (payload == null) ? bodyParams.asFormUrlEncodedString() : payload; + try { + return body.getBytes(getCharset()); + } catch (UnsupportedEncodingException uee) { + throw new OAuthException("Unsupported Charset: " + getCharset(), uee); + } + } + + @Override + public String toString() { + return String.format("@Request(%s %s)", getVerb(), getUrl()); + } + + public Verb getVerb() { + return verb; + } + + public Map getHeaders() { + return headers; + } + + public String getCharset() { + return charset == null ? Charset.defaultCharset().name() : charset; + } + + /** + * Set the charset of the body of the request + * + * @param charsetName name of the charset of the request + */ + public void setCharset(String charsetName) { + charset = charsetName; + } + + /** + * Sets whether the underlying Http Connection is persistent or not. + * + * @param connectionKeepAlive boolean + * + * @see http://download.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html + */ + public void setConnectionKeepAlive(boolean connectionKeepAlive) { + this.connectionKeepAlive = connectionKeepAlive; + } + + /** + * Sets whether the underlying Http Connection follows redirects or not. + * + * Defaults to true (follow redirects) + * + * @see http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html#setInstanceFollowRedirects(boolean) + * @param followRedirects boolean + */ + public void setFollowRedirects(boolean followRedirects) { + this.followRedirects = followRedirects; + } + + public boolean isConnectionKeepAlive() { + return connectionKeepAlive; + } + + public boolean isFollowRedirects() { + return followRedirects; + } + + public OAuthService getService() { + return service; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConfig.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConfig.java index d5bba4899..ab421dd32 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConfig.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConfig.java @@ -1,118 +1,118 @@ -package com.github.scribejava.core.model; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Parameter object that groups OAuth config values - */ -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 final String state; - private final String responseType; - private final String userAgent; - - //sync only version - private final Integer connectTimeout; - private final Integer readTimeout; - - //async version only - //ning 1.9 - private com.ning.http.client.AsyncHttpClientConfig ningAsyncHttpClientConfig; - private String ningAsyncHttpProviderClassName; - //AHC 2.0 - private org.asynchttpclient.AsyncHttpClientConfig ahcAsyncHttpClientConfig; - - public OAuthConfig(String key, String secret) { - this(key, secret, null, null, null, null, null, null, null, null, null, null, null, null); - } - - public OAuthConfig(String apiKey, String apiSecret, String callback, SignatureType signatureType, String scope, - OutputStream debugStream, String state, String responseType, String userAgent, Integer connectTimeout, - Integer readTimeout, com.ning.http.client.AsyncHttpClientConfig ningAsyncHttpClientConfig, - String ningAsyncHttpProviderClassName, org.asynchttpclient.AsyncHttpClientConfig ahcAsyncHttpClientConfig) { - this.apiKey = apiKey; - this.apiSecret = apiSecret; - this.callback = callback; - this.signatureType = signatureType; - this.scope = scope; - this.debugStream = debugStream; - this.state = state; - this.responseType = responseType; - this.userAgent = userAgent; - this.connectTimeout = connectTimeout; - this.readTimeout = readTimeout; - this.ningAsyncHttpClientConfig = ningAsyncHttpClientConfig; - this.ningAsyncHttpProviderClassName = ningAsyncHttpProviderClassName; - this.ahcAsyncHttpClientConfig = ahcAsyncHttpClientConfig; - } - - public String getApiKey() { - return apiKey; - } - - public String getApiSecret() { - return apiSecret; - } - - public String getCallback() { - return callback; - } - - public SignatureType getSignatureType() { - return signatureType; - } - - public String getScope() { - return scope; - } - - public String getState() { - return state; - } - - public String getResponseType() { - return responseType; - } - - public String getUserAgent() { - return userAgent; - } - - public void log(String message) { - if (debugStream != null) { - message += '\n'; - try { - debugStream.write(message.getBytes("UTF8")); - } catch (IOException | RuntimeException e) { - throw new RuntimeException("there were problems while writting to the debug stream", e); - } - } - } - - public Integer getConnectTimeout() { - return connectTimeout; - } - - public Integer getReadTimeout() { - return readTimeout; - } - - public com.ning.http.client.AsyncHttpClientConfig getNingAsyncHttpClientConfig() { - return ningAsyncHttpClientConfig; - } - - public String getNingAsyncHttpProviderClassName() { - return ningAsyncHttpProviderClassName; - } - - public org.asynchttpclient.AsyncHttpClientConfig getAhcAsyncHttpClientConfig() { - return ahcAsyncHttpClientConfig; - } -} +package com.github.scribejava.core.model; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Parameter object that groups OAuth config values + */ +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 final String state; + private final String responseType; + private final String userAgent; + + //sync only version + private final Integer connectTimeout; + private final Integer readTimeout; + + //async version only + //ning 1.9 + private com.ning.http.client.AsyncHttpClientConfig ningAsyncHttpClientConfig; + private String ningAsyncHttpProviderClassName; + //AHC 2.0 + private org.asynchttpclient.AsyncHttpClientConfig ahcAsyncHttpClientConfig; + + public OAuthConfig(String key, String secret) { + this(key, secret, null, null, null, null, null, null, null, null, null, null, null, null); + } + + public OAuthConfig(String apiKey, String apiSecret, String callback, SignatureType signatureType, String scope, + OutputStream debugStream, String state, String responseType, String userAgent, Integer connectTimeout, + Integer readTimeout, com.ning.http.client.AsyncHttpClientConfig ningAsyncHttpClientConfig, + String ningAsyncHttpProviderClassName, org.asynchttpclient.AsyncHttpClientConfig ahcAsyncHttpClientConfig) { + this.apiKey = apiKey; + this.apiSecret = apiSecret; + this.callback = callback; + this.signatureType = signatureType; + this.scope = scope; + this.debugStream = debugStream; + this.state = state; + this.responseType = responseType; + this.userAgent = userAgent; + this.connectTimeout = connectTimeout; + this.readTimeout = readTimeout; + this.ningAsyncHttpClientConfig = ningAsyncHttpClientConfig; + this.ningAsyncHttpProviderClassName = ningAsyncHttpProviderClassName; + this.ahcAsyncHttpClientConfig = ahcAsyncHttpClientConfig; + } + + public String getApiKey() { + return apiKey; + } + + public String getApiSecret() { + return apiSecret; + } + + public String getCallback() { + return callback; + } + + public SignatureType getSignatureType() { + return signatureType; + } + + public String getScope() { + return scope; + } + + public String getState() { + return state; + } + + public String getResponseType() { + return responseType; + } + + public String getUserAgent() { + return userAgent; + } + + public void log(String message) { + if (debugStream != null) { + message += '\n'; + try { + debugStream.write(message.getBytes("UTF8")); + } catch (IOException | RuntimeException e) { + throw new RuntimeException("there were problems while writting to the debug stream", e); + } + } + } + + public Integer getConnectTimeout() { + return connectTimeout; + } + + public Integer getReadTimeout() { + return readTimeout; + } + + public com.ning.http.client.AsyncHttpClientConfig getNingAsyncHttpClientConfig() { + return ningAsyncHttpClientConfig; + } + + public String getNingAsyncHttpProviderClassName() { + return ningAsyncHttpProviderClassName; + } + + public org.asynchttpclient.AsyncHttpClientConfig getAhcAsyncHttpClientConfig() { + return ahcAsyncHttpClientConfig; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConstants.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConstants.java index 2cf8d236a..0aaf575e8 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConstants.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConstants.java @@ -1,44 +1,44 @@ -package com.github.scribejava.core.model; - -/** - * This class contains OAuth constants, used project-wide - */ -public interface OAuthConstants { - - String TIMESTAMP = "oauth_timestamp"; - String SIGN_METHOD = "oauth_signature_method"; - String SIGNATURE = "oauth_signature"; - String CONSUMER_SECRET = "oauth_consumer_secret"; - String CONSUMER_KEY = "oauth_consumer_key"; - String CALLBACK = "oauth_callback"; - String VERSION = "oauth_version"; - String NONCE = "oauth_nonce"; - String REALM = "realm"; - String PARAM_PREFIX = "oauth_"; - String TOKEN = "oauth_token"; - String TOKEN_SECRET = "oauth_token_secret"; - String OUT_OF_BAND = "oob"; - String VERIFIER = "oauth_verifier"; - String HEADER = "Authorization"; - String SCOPE = "scope"; - String BASIC = "Basic"; - - // OAuth 2.0 - String ACCESS_TOKEN = "access_token"; - String CLIENT_ID = "client_id"; - String CLIENT_SECRET = "client_secret"; - String REDIRECT_URI = "redirect_uri"; - String CODE = "code"; - String REFRESH_TOKEN = "refresh_token"; - String GRANT_TYPE = "grant_type"; - String AUTHORIZATION_CODE = "authorization_code"; - String STATE = "state"; - String USERNAME = "username"; - String PASSWORD = "password"; - String RESPONSE_TYPE = "response_type"; - String RESPONSE_TYPE_CODE = "code"; - - //not OAuth specific - String USER_AGENT_HEADER_NAME = "User-Agent"; - -} +package com.github.scribejava.core.model; + +/** + * This class contains OAuth constants, used project-wide + */ +public interface OAuthConstants { + + String TIMESTAMP = "oauth_timestamp"; + String SIGN_METHOD = "oauth_signature_method"; + String SIGNATURE = "oauth_signature"; + String CONSUMER_SECRET = "oauth_consumer_secret"; + String CONSUMER_KEY = "oauth_consumer_key"; + String CALLBACK = "oauth_callback"; + String VERSION = "oauth_version"; + String NONCE = "oauth_nonce"; + String REALM = "realm"; + String PARAM_PREFIX = "oauth_"; + String TOKEN = "oauth_token"; + String TOKEN_SECRET = "oauth_token_secret"; + String OUT_OF_BAND = "oob"; + String VERIFIER = "oauth_verifier"; + String HEADER = "Authorization"; + String SCOPE = "scope"; + String BASIC = "Basic"; + + // OAuth 2.0 + String ACCESS_TOKEN = "access_token"; + String CLIENT_ID = "client_id"; + String CLIENT_SECRET = "client_secret"; + String REDIRECT_URI = "redirect_uri"; + String CODE = "code"; + String REFRESH_TOKEN = "refresh_token"; + String GRANT_TYPE = "grant_type"; + String AUTHORIZATION_CODE = "authorization_code"; + String STATE = "state"; + String USERNAME = "username"; + String PASSWORD = "password"; + String RESPONSE_TYPE = "response_type"; + String RESPONSE_TYPE_CODE = "code"; + + //not OAuth specific + String USER_AGENT_HEADER_NAME = "User-Agent"; + +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthRequest.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthRequest.java index 230cd15b9..bfd904917 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthRequest.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthRequest.java @@ -1,92 +1,92 @@ -package com.github.scribejava.core.model; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Map; -import com.github.scribejava.core.exceptions.OAuthConnectionException; -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.oauth.OAuthService; - -public class OAuthRequest extends AbstractRequest { - - private HttpURLConnection connection; - - public OAuthRequest(Verb verb, String url, OAuthService service) { - super(verb, url, service); - } - - /** - * Execute the request and return a {@link Response} - * - * @return Http Response - * - * @throws RuntimeException if the connection cannot be created. - */ - public Response send() { - final ForceTypeOfHttpRequest forceTypeOfHttpRequest = ScribeJavaConfig.getForceTypeOfHttpRequests(); - - if (ForceTypeOfHttpRequest.FORCE_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - throw new OAuthException("Cannot use sync operations, only async"); - } - if (ForceTypeOfHttpRequest.PREFER_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - getService().getConfig().log("Cannot use sync operations, only async"); - } - try { - createConnection(); - return doSend(); - } catch (IOException | RuntimeException e) { - throw new OAuthConnectionException(getCompleteUrl(), e); - } - } - - Response doSend() throws IOException { - final Verb verb = getVerb(); - connection.setRequestMethod(verb.name()); - final OAuthConfig config = getService().getConfig(); - if (config.getConnectTimeout() != null) { - connection.setConnectTimeout(config.getConnectTimeout()); - } - if (config.getReadTimeout() != null) { - connection.setReadTimeout(config.getReadTimeout()); - } - addHeaders(); - if (hasBodyContent()) { - addBody(getByteBodyContents()); - } - return new Response(connection); - } - - private void createConnection() throws IOException { - final String completeUrl = getCompleteUrl(); - if (connection == null) { - System.setProperty("http.keepAlive", isConnectionKeepAlive() ? "true" : "false"); - connection = (HttpURLConnection) new URL(completeUrl).openConnection(); - connection.setInstanceFollowRedirects(isFollowRedirects()); - } - } - - void addHeaders() { - for (Map.Entry entry : getHeaders().entrySet()) { - connection.setRequestProperty(entry.getKey(), entry.getValue()); - } - final String userAgent = getService().getConfig().getUserAgent(); - if (userAgent != null) { - connection.setRequestProperty(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent); - } - } - - void addBody(byte[] content) throws IOException { - connection.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.length)); - - if (connection.getRequestProperty(CONTENT_TYPE) == null) { - connection.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); - } - connection.setDoOutput(true); - connection.getOutputStream().write(content); - } - - void setConnection(HttpURLConnection connection) { - this.connection = connection; - } -} +package com.github.scribejava.core.model; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Map; +import com.github.scribejava.core.exceptions.OAuthConnectionException; +import com.github.scribejava.core.exceptions.OAuthException; +import com.github.scribejava.core.oauth.OAuthService; + +public class OAuthRequest extends AbstractRequest { + + private HttpURLConnection connection; + + public OAuthRequest(Verb verb, String url, OAuthService service) { + super(verb, url, service); + } + + /** + * Execute the request and return a {@link Response} + * + * @return Http Response + * + * @throws RuntimeException if the connection cannot be created. + */ + public Response send() { + final ForceTypeOfHttpRequest forceTypeOfHttpRequest = ScribeJavaConfig.getForceTypeOfHttpRequests(); + + if (ForceTypeOfHttpRequest.FORCE_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { + throw new OAuthException("Cannot use sync operations, only async"); + } + if (ForceTypeOfHttpRequest.PREFER_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { + getService().getConfig().log("Cannot use sync operations, only async"); + } + try { + createConnection(); + return doSend(); + } catch (IOException | RuntimeException e) { + throw new OAuthConnectionException(getCompleteUrl(), e); + } + } + + Response doSend() throws IOException { + final Verb verb = getVerb(); + connection.setRequestMethod(verb.name()); + final OAuthConfig config = getService().getConfig(); + if (config.getConnectTimeout() != null) { + connection.setConnectTimeout(config.getConnectTimeout()); + } + if (config.getReadTimeout() != null) { + connection.setReadTimeout(config.getReadTimeout()); + } + addHeaders(); + if (hasBodyContent()) { + addBody(getByteBodyContents()); + } + return new Response(connection); + } + + private void createConnection() throws IOException { + final String completeUrl = getCompleteUrl(); + if (connection == null) { + System.setProperty("http.keepAlive", isConnectionKeepAlive() ? "true" : "false"); + connection = (HttpURLConnection) new URL(completeUrl).openConnection(); + connection.setInstanceFollowRedirects(isFollowRedirects()); + } + } + + void addHeaders() { + for (Map.Entry entry : getHeaders().entrySet()) { + connection.setRequestProperty(entry.getKey(), entry.getValue()); + } + final String userAgent = getService().getConfig().getUserAgent(); + if (userAgent != null) { + connection.setRequestProperty(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent); + } + } + + void addBody(byte[] content) throws IOException { + connection.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.length)); + + if (connection.getRequestProperty(CONTENT_TYPE) == null) { + connection.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); + } + connection.setDoOutput(true); + connection.getOutputStream().write(content); + } + + void setConnection(HttpURLConnection connection) { + this.connection = connection; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthRequestAsync.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthRequestAsync.java index 1a92f0699..bf5104f9f 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthRequestAsync.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthRequestAsync.java @@ -1,36 +1,36 @@ -package com.github.scribejava.core.model; - -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.oauth.OAuthService; - -import java.io.IOException; -import java.util.concurrent.Future; - -public class OAuthRequestAsync extends AbstractRequest { - - public OAuthRequestAsync(Verb verb, String url, OAuthService service) { - super(verb, url, service); - } - - public Future sendAsync(OAuthAsyncRequestCallback callback, ResponseConverter converter) { - final ForceTypeOfHttpRequest forceTypeOfHttpRequest = ScribeJavaConfig.getForceTypeOfHttpRequests(); - if (ForceTypeOfHttpRequest.FORCE_SYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - throw new OAuthException("Cannot use async operations, only sync"); - } - final OAuthService service = getService(); - final OAuthConfig config = service.getConfig(); - if (ForceTypeOfHttpRequest.PREFER_SYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - config.log("Cannot use async operations, only sync"); - } - return service.executeAsync(getHeaders(), getVerb(), getCompleteUrl(), getBodyContents(), callback, converter); - } - - public Future sendAsync(OAuthAsyncRequestCallback callback) { - return sendAsync(callback, null); - } - - public interface ResponseConverter { - - T convert(Response response) throws IOException; - } -} +package com.github.scribejava.core.model; + +import com.github.scribejava.core.exceptions.OAuthException; +import com.github.scribejava.core.oauth.OAuthService; + +import java.io.IOException; +import java.util.concurrent.Future; + +public class OAuthRequestAsync extends AbstractRequest { + + public OAuthRequestAsync(Verb verb, String url, OAuthService service) { + super(verb, url, service); + } + + public Future sendAsync(OAuthAsyncRequestCallback callback, ResponseConverter converter) { + final ForceTypeOfHttpRequest forceTypeOfHttpRequest = ScribeJavaConfig.getForceTypeOfHttpRequests(); + if (ForceTypeOfHttpRequest.FORCE_SYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { + throw new OAuthException("Cannot use async operations, only sync"); + } + final OAuthService service = getService(); + final OAuthConfig config = service.getConfig(); + if (ForceTypeOfHttpRequest.PREFER_SYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { + config.log("Cannot use async operations, only sync"); + } + return service.executeAsync(getHeaders(), getVerb(), getCompleteUrl(), getBodyContents(), callback, converter); + } + + public Future sendAsync(OAuthAsyncRequestCallback callback) { + return sendAsync(callback, null); + } + + public interface ResponseConverter { + + T convert(Response response) throws IOException; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/ParameterList.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/ParameterList.java index 39d806652..21d111d72 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/ParameterList.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/ParameterList.java @@ -1,100 +1,100 @@ -package com.github.scribejava.core.model; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import com.github.scribejava.core.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; - -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 params; - - public ParameterList() { - params = new ArrayList<>(); - } - - ParameterList(List params) { - this.params = new ArrayList<>(params); - } - - public ParameterList(Map map) { - this(); - if (map != null && !map.isEmpty()) { - for (Map.Entry 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"); - final String queryString = asFormUrlEncodedString(); - if (queryString.equals(EMPTY_STRING)) { - return url; - } else { - return url - + (url.indexOf(QUERY_STRING_SEPARATOR) == -1 ? QUERY_STRING_SEPARATOR : PARAM_SEPARATOR) - + queryString; - } - } - - public String asOauthBaseString() { - return OAuthEncoder.encode(asFormUrlEncodedString()); - } - - public String asFormUrlEncodedString() { - if (params.isEmpty()) { - return EMPTY_STRING; - } - - final StringBuilder builder = new StringBuilder(); - for (Parameter p : params) { - builder.append(PARAM_SEPARATOR).append(p.asUrlEncodedPair()); - } - return builder.substring(1); - } - - public void addAll(ParameterList other) { - params.addAll(other.getParams()); - } - - public void addQuerystring(String queryString) { - if (queryString != null && !queryString.isEmpty()) { - for (String param : queryString.split(PARAM_SEPARATOR)) { - final String[] pair = param.split(PAIR_SEPARATOR); - final String key = OAuthEncoder.decode(pair[0]); - final 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 List getParams() { - return params; - } - - public ParameterList sort() { - final ParameterList sorted = new ParameterList(params); - Collections.sort(sorted.getParams()); - return sorted; - } -} +package com.github.scribejava.core.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import com.github.scribejava.core.utils.OAuthEncoder; +import com.github.scribejava.core.utils.Preconditions; + +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 params; + + public ParameterList() { + params = new ArrayList<>(); + } + + ParameterList(List params) { + this.params = new ArrayList<>(params); + } + + public ParameterList(Map map) { + this(); + if (map != null && !map.isEmpty()) { + for (Map.Entry 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"); + final String queryString = asFormUrlEncodedString(); + if (queryString.equals(EMPTY_STRING)) { + return url; + } else { + return url + + (url.indexOf(QUERY_STRING_SEPARATOR) == -1 ? QUERY_STRING_SEPARATOR : PARAM_SEPARATOR) + + queryString; + } + } + + public String asOauthBaseString() { + return OAuthEncoder.encode(asFormUrlEncodedString()); + } + + public String asFormUrlEncodedString() { + if (params.isEmpty()) { + return EMPTY_STRING; + } + + final StringBuilder builder = new StringBuilder(); + for (Parameter p : params) { + builder.append(PARAM_SEPARATOR).append(p.asUrlEncodedPair()); + } + return builder.substring(1); + } + + public void addAll(ParameterList other) { + params.addAll(other.getParams()); + } + + public void addQuerystring(String queryString) { + if (queryString != null && !queryString.isEmpty()) { + for (String param : queryString.split(PARAM_SEPARATOR)) { + final String[] pair = param.split(PAIR_SEPARATOR); + final String key = OAuthEncoder.decode(pair[0]); + final 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 List getParams() { + return params; + } + + public ParameterList sort() { + final ParameterList sorted = new ParameterList(params); + Collections.sort(sorted.getParams()); + return sorted; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/Response.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/Response.java index 869066788..e3d9a0fd1 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/Response.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/Response.java @@ -1,123 +1,123 @@ -package com.github.scribejava.core.model; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.utils.StreamUtils; - -public class Response { - - private int code; - private String message; - private String body; - private InputStream stream; - private Map headers; - - public Response(int code, String message, Map headers, String body, InputStream stream) { - this.code = code; - this.headers = headers; - this.body = body; - this.message = message; - this.stream = stream; - } - - Response(HttpURLConnection connection) throws IOException { - try { - connection.connect(); - code = connection.getResponseCode(); - message = connection.getResponseMessage(); - headers = parseHeaders(connection); - stream = isSuccessful() ? connection.getInputStream() : connection.getErrorStream(); - } catch (UnknownHostException e) { - throw new OAuthException("The IP address of a host could not be determined.", e); - } - } - - private String parseBodyContents() throws IOException { - if ("gzip".equals(getHeader("Content-Encoding"))) { - body = StreamUtils.getGzipStreamContents(getStream()); - } else { - body = StreamUtils.getStreamContents(getStream()); - } - return body; - } - - private Map parseHeaders(HttpURLConnection conn) { - final Map headers = new HashMap<>(); - for (String key : conn.getHeaderFields().keySet()) { - headers.put(key, conn.getHeaderFields().get(key).get(0)); - } - return headers; - } - - public final boolean isSuccessful() { - return getCode() >= 200 && getCode() < 400; - } - - public String getBody() throws IOException { - return body == null ? parseBodyContents() : body; - } - - /** - * Obtains the meaningful stream of the HttpUrlConnection, either inputStream or errorInputStream, depending on the - * status code - * - * @return input stream / error stream - */ - public InputStream getStream() { - return stream; - } - - /** - * Obtains the HTTP status code - * - * @return the status code - */ - public final int getCode() { - return code; - } - - /** - * Obtains the HTTP status message. Returns null if the message can not be discerned from the response - * (not valid HTTP) - * - * @return the status message - */ - public String getMessage() { - return message; - } - - /** - * Obtains a {@link Map} containing the HTTP Response Headers - * - * @return headers - */ - public Map getHeaders() { - return headers; - } - - /** - * Obtains a single HTTP Header value, or null if undefined - * - * @param name the header name. - * - * @return header value or null. - */ - public String getHeader(String name) { - return headers.get(name); - } - - @Override - public String toString() { - return "Response{" + - "code=" + code + - ", message='" + message + '\'' + - ", body='" + body + '\'' + - ", headers=" + headers + - '}'; - } -} +package com.github.scribejava.core.model; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; +import com.github.scribejava.core.exceptions.OAuthException; +import com.github.scribejava.core.utils.StreamUtils; + +public class Response { + + private int code; + private String message; + private String body; + private InputStream stream; + private Map headers; + + public Response(int code, String message, Map headers, String body, InputStream stream) { + this.code = code; + this.headers = headers; + this.body = body; + this.message = message; + this.stream = stream; + } + + Response(HttpURLConnection connection) throws IOException { + try { + connection.connect(); + code = connection.getResponseCode(); + message = connection.getResponseMessage(); + headers = parseHeaders(connection); + stream = isSuccessful() ? connection.getInputStream() : connection.getErrorStream(); + } catch (UnknownHostException e) { + throw new OAuthException("The IP address of a host could not be determined.", e); + } + } + + private String parseBodyContents() throws IOException { + if ("gzip".equals(getHeader("Content-Encoding"))) { + body = StreamUtils.getGzipStreamContents(getStream()); + } else { + body = StreamUtils.getStreamContents(getStream()); + } + return body; + } + + private Map parseHeaders(HttpURLConnection conn) { + final Map headers = new HashMap<>(); + for (String key : conn.getHeaderFields().keySet()) { + headers.put(key, conn.getHeaderFields().get(key).get(0)); + } + return headers; + } + + public final boolean isSuccessful() { + return getCode() >= 200 && getCode() < 400; + } + + public String getBody() throws IOException { + return body == null ? parseBodyContents() : body; + } + + /** + * Obtains the meaningful stream of the HttpUrlConnection, either inputStream or errorInputStream, depending on the + * status code + * + * @return input stream / error stream + */ + public InputStream getStream() { + return stream; + } + + /** + * Obtains the HTTP status code + * + * @return the status code + */ + public final int getCode() { + return code; + } + + /** + * Obtains the HTTP status message. Returns null if the message can not be discerned from the response + * (not valid HTTP) + * + * @return the status message + */ + public String getMessage() { + return message; + } + + /** + * Obtains a {@link Map} containing the HTTP Response Headers + * + * @return headers + */ + public Map getHeaders() { + return headers; + } + + /** + * Obtains a single HTTP Header value, or null if undefined + * + * @param name the header name. + * + * @return header value or null. + */ + public String getHeader(String name) { + return headers.get(name); + } + + @Override + public String toString() { + return "Response{" + + "code=" + code + + ", message='" + message + '\'' + + ", body='" + body + '\'' + + ", headers=" + headers + + '}'; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth10aService.java b/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth10aService.java index e707486bc..e777fff52 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth10aService.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth10aService.java @@ -1,201 +1,201 @@ -package com.github.scribejava.core.oauth; - -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.Future; -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.AbstractRequest; -import com.github.scribejava.core.model.OAuth1AccessToken; -import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.model.OAuthAsyncRequestCallback; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.OAuthRequest; -import com.github.scribejava.core.model.OAuthRequestAsync; -import com.github.scribejava.core.model.Response; -import com.github.scribejava.core.services.Base64Encoder; -import com.github.scribejava.core.utils.MapUtils; - -/** - * OAuth 1.0a implementation of {@link OAuthService} - */ -public class OAuth10aService extends OAuthService { - - private static final String VERSION = "1.0"; - private final DefaultApi10a api; - - /** - * Default constructor - * - * @param api OAuth1.0a api information - * @param config OAuth 1.0a configuration param object - */ - public OAuth10aService(DefaultApi10a api, OAuthConfig config) { - super(config); - this.api = api; - } - - public final OAuth1RequestToken getRequestToken() throws IOException { - final OAuthConfig config = getConfig(); - config.log("obtaining request token from " + api.getRequestTokenEndpoint()); - final OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint(), this); - - prepareRequestTokenRequest(request); - - config.log("sending request..."); - final Response response = request.send(); - final String body = response.getBody(); - - config.log("response status code: " + response.getCode()); - config.log("response body: " + body); - return api.getRequestTokenExtractor().extract(body); - } - - public final Future getRequestTokenAsync( - OAuthAsyncRequestCallback callback) { - final OAuthConfig config = getConfig(); - config.log("async obtaining request token from " + api.getRequestTokenEndpoint()); - final OAuthRequestAsync request - = new OAuthRequestAsync(api.getRequestTokenVerb(), api.getRequestTokenEndpoint(), this); - prepareRequestTokenRequest(request); - return request.sendAsync(callback, new OAuthRequestAsync.ResponseConverter() { - @Override - public OAuth1RequestToken convert(Response response) throws IOException { - return getApi().getRequestTokenExtractor().extract(response.getBody()); - } - }); - } - - protected void prepareRequestTokenRequest(AbstractRequest request) { - final OAuthConfig config = getConfig(); - config.log("setting oauth_callback to " + config.getCallback()); - request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback()); - addOAuthParams(request, ""); - appendSignature(request); - } - - private void addOAuthParams(AbstractRequest request, String tokenSecret) { - final OAuthConfig config = getConfig(); - request.addOAuthParameter(OAuthConstants.TIMESTAMP, api.getTimestampService().getTimestampInSeconds()); - request.addOAuthParameter(OAuthConstants.NONCE, api.getTimestampService().getNonce()); - request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey()); - request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod()); - request.addOAuthParameter(OAuthConstants.VERSION, getVersion()); - final String scope = config.getScope(); - if (scope != null) { - request.addOAuthParameter(OAuthConstants.SCOPE, scope); - } - request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, tokenSecret)); - - config.log("appended additional OAuth parameters: " + MapUtils.toString(request.getOauthParameters())); - } - - public final OAuth1AccessToken getAccessToken(OAuth1RequestToken requestToken, String oauthVerifier) - throws IOException { - final OAuthConfig config = getConfig(); - config.log("obtaining access token from " + api.getAccessTokenEndpoint()); - final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this); - prepareAccessTokenRequest(request, requestToken, oauthVerifier); - final Response response = request.send(); - return api.getAccessTokenExtractor().extract(response.getBody()); - } - - /** - * Start the request to retrieve the access token. The optionally provided - * callback will be called with the Token when it is available. - * - * @param requestToken request token (obtained previously or null) - * @param oauthVerifier oauth_verifier - * @param callback optional callback - * @return Future - */ - public final Future getAccessTokenAsync(OAuth1RequestToken requestToken, String oauthVerifier, - OAuthAsyncRequestCallback callback) { - final OAuthConfig config = getConfig(); - config.log("async obtaining access token from " + api.getAccessTokenEndpoint()); - final OAuthRequestAsync request - = new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this); - prepareAccessTokenRequest(request, requestToken, oauthVerifier); - return request.sendAsync(callback, new OAuthRequestAsync.ResponseConverter() { - @Override - public OAuth1AccessToken convert(Response response) throws IOException { - return getApi().getAccessTokenExtractor().extract(response.getBody()); - } - }); - } - - protected void prepareAccessTokenRequest(AbstractRequest request, OAuth1RequestToken requestToken, - String oauthVerifier) { - final OAuthConfig config = getConfig(); - request.addOAuthParameter(OAuthConstants.TOKEN, requestToken.getToken()); - request.addOAuthParameter(OAuthConstants.VERIFIER, oauthVerifier); - config.log("setting token to: " + requestToken + " and verifier to: " + oauthVerifier); - addOAuthParams(request, requestToken.getTokenSecret()); - appendSignature(request); - } - - public void signRequest(OAuth1AccessToken token, AbstractRequest request) { - final OAuthConfig config = getConfig(); - config.log("signing request: " + request.getCompleteUrl()); - - if (!token.isEmpty() || api.isEmptyOAuthTokenParamIsRequired()) { - request.addOAuthParameter(OAuthConstants.TOKEN, token.getToken()); - } - config.log("setting token to: " + token); - addOAuthParams(request, token.getTokenSecret()); - appendSignature(request); - } - - @Override - public String getVersion() { - return VERSION; - } - - /** - * Returns the URL where you should redirect your users to authenticate your - * application. - * - * @param requestToken the request token you need to authorize - * @return the URL where you should redirect your users - */ - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return api.getAuthorizationUrl(requestToken); - } - - private String getSignature(AbstractRequest request, String tokenSecret) { - final OAuthConfig config = getConfig(); - config.log("generating signature..."); - config.log("using base64 encoder: " + Base64Encoder.type()); - final String baseString = api.getBaseStringExtractor().extract(request); - final String signature = api.getSignatureService().getSignature(baseString, config.getApiSecret(), tokenSecret); - - config.log("base string is: " + baseString); - config.log("signature is: " + signature); - return signature; - } - - private void appendSignature(AbstractRequest request) { - final OAuthConfig config = getConfig(); - switch (config.getSignatureType()) { - case Header: - config.log("using Http Header signature"); - - final String oauthHeader = api.getHeaderExtractor().extract(request); - request.addHeader(OAuthConstants.HEADER, oauthHeader); - break; - case QueryString: - config.log("using Querystring signature"); - - for (Map.Entry entry : request.getOauthParameters().entrySet()) { - request.addQuerystringParameter(entry.getKey(), entry.getValue()); - } - break; - default: - throw new IllegalStateException("Unknown new Signature Type '" + config.getSignatureType() + "'."); - } - } - - public DefaultApi10a getApi() { - return api; - } -} +package com.github.scribejava.core.oauth; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.Future; +import com.github.scribejava.core.builder.api.DefaultApi10a; +import com.github.scribejava.core.model.AbstractRequest; +import com.github.scribejava.core.model.OAuth1AccessToken; +import com.github.scribejava.core.model.OAuth1RequestToken; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.OAuthRequestAsync; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.services.Base64Encoder; +import com.github.scribejava.core.utils.MapUtils; + +/** + * OAuth 1.0a implementation of {@link OAuthService} + */ +public class OAuth10aService extends OAuthService { + + private static final String VERSION = "1.0"; + private final DefaultApi10a api; + + /** + * Default constructor + * + * @param api OAuth1.0a api information + * @param config OAuth 1.0a configuration param object + */ + public OAuth10aService(DefaultApi10a api, OAuthConfig config) { + super(config); + this.api = api; + } + + public final OAuth1RequestToken getRequestToken() throws IOException { + final OAuthConfig config = getConfig(); + config.log("obtaining request token from " + api.getRequestTokenEndpoint()); + final OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint(), this); + + prepareRequestTokenRequest(request); + + config.log("sending request..."); + final Response response = request.send(); + final String body = response.getBody(); + + config.log("response status code: " + response.getCode()); + config.log("response body: " + body); + return api.getRequestTokenExtractor().extract(body); + } + + public final Future getRequestTokenAsync( + OAuthAsyncRequestCallback callback) { + final OAuthConfig config = getConfig(); + config.log("async obtaining request token from " + api.getRequestTokenEndpoint()); + final OAuthRequestAsync request + = new OAuthRequestAsync(api.getRequestTokenVerb(), api.getRequestTokenEndpoint(), this); + prepareRequestTokenRequest(request); + return request.sendAsync(callback, new OAuthRequestAsync.ResponseConverter() { + @Override + public OAuth1RequestToken convert(Response response) throws IOException { + return getApi().getRequestTokenExtractor().extract(response.getBody()); + } + }); + } + + protected void prepareRequestTokenRequest(AbstractRequest request) { + final OAuthConfig config = getConfig(); + config.log("setting oauth_callback to " + config.getCallback()); + request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback()); + addOAuthParams(request, ""); + appendSignature(request); + } + + private void addOAuthParams(AbstractRequest request, String tokenSecret) { + final OAuthConfig config = getConfig(); + request.addOAuthParameter(OAuthConstants.TIMESTAMP, api.getTimestampService().getTimestampInSeconds()); + request.addOAuthParameter(OAuthConstants.NONCE, api.getTimestampService().getNonce()); + request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey()); + request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod()); + request.addOAuthParameter(OAuthConstants.VERSION, getVersion()); + final String scope = config.getScope(); + if (scope != null) { + request.addOAuthParameter(OAuthConstants.SCOPE, scope); + } + request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, tokenSecret)); + + config.log("appended additional OAuth parameters: " + MapUtils.toString(request.getOauthParameters())); + } + + public final OAuth1AccessToken getAccessToken(OAuth1RequestToken requestToken, String oauthVerifier) + throws IOException { + final OAuthConfig config = getConfig(); + config.log("obtaining access token from " + api.getAccessTokenEndpoint()); + final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this); + prepareAccessTokenRequest(request, requestToken, oauthVerifier); + final Response response = request.send(); + return api.getAccessTokenExtractor().extract(response.getBody()); + } + + /** + * Start the request to retrieve the access token. The optionally provided + * callback will be called with the Token when it is available. + * + * @param requestToken request token (obtained previously or null) + * @param oauthVerifier oauth_verifier + * @param callback optional callback + * @return Future + */ + public final Future getAccessTokenAsync(OAuth1RequestToken requestToken, String oauthVerifier, + OAuthAsyncRequestCallback callback) { + final OAuthConfig config = getConfig(); + config.log("async obtaining access token from " + api.getAccessTokenEndpoint()); + final OAuthRequestAsync request + = new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this); + prepareAccessTokenRequest(request, requestToken, oauthVerifier); + return request.sendAsync(callback, new OAuthRequestAsync.ResponseConverter() { + @Override + public OAuth1AccessToken convert(Response response) throws IOException { + return getApi().getAccessTokenExtractor().extract(response.getBody()); + } + }); + } + + protected void prepareAccessTokenRequest(AbstractRequest request, OAuth1RequestToken requestToken, + String oauthVerifier) { + final OAuthConfig config = getConfig(); + request.addOAuthParameter(OAuthConstants.TOKEN, requestToken.getToken()); + request.addOAuthParameter(OAuthConstants.VERIFIER, oauthVerifier); + config.log("setting token to: " + requestToken + " and verifier to: " + oauthVerifier); + addOAuthParams(request, requestToken.getTokenSecret()); + appendSignature(request); + } + + public void signRequest(OAuth1AccessToken token, AbstractRequest request) { + final OAuthConfig config = getConfig(); + config.log("signing request: " + request.getCompleteUrl()); + + if (!token.isEmpty() || api.isEmptyOAuthTokenParamIsRequired()) { + request.addOAuthParameter(OAuthConstants.TOKEN, token.getToken()); + } + config.log("setting token to: " + token); + addOAuthParams(request, token.getTokenSecret()); + appendSignature(request); + } + + @Override + public String getVersion() { + return VERSION; + } + + /** + * Returns the URL where you should redirect your users to authenticate your + * application. + * + * @param requestToken the request token you need to authorize + * @return the URL where you should redirect your users + */ + public String getAuthorizationUrl(OAuth1RequestToken requestToken) { + return api.getAuthorizationUrl(requestToken); + } + + private String getSignature(AbstractRequest request, String tokenSecret) { + final OAuthConfig config = getConfig(); + config.log("generating signature..."); + config.log("using base64 encoder: " + Base64Encoder.type()); + final String baseString = api.getBaseStringExtractor().extract(request); + final String signature = api.getSignatureService().getSignature(baseString, config.getApiSecret(), tokenSecret); + + config.log("base string is: " + baseString); + config.log("signature is: " + signature); + return signature; + } + + private void appendSignature(AbstractRequest request) { + final OAuthConfig config = getConfig(); + switch (config.getSignatureType()) { + case Header: + config.log("using Http Header signature"); + + final String oauthHeader = api.getHeaderExtractor().extract(request); + request.addHeader(OAuthConstants.HEADER, oauthHeader); + break; + case QueryString: + config.log("using Querystring signature"); + + for (Map.Entry entry : request.getOauthParameters().entrySet()) { + request.addQuerystringParameter(entry.getKey(), entry.getValue()); + } + break; + default: + throw new IllegalStateException("Unknown new Signature Type '" + config.getSignatureType() + "'."); + } + } + + public DefaultApi10a getApi() { + return api; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth20Service.java b/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth20Service.java index c863951b4..0839c3d86 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth20Service.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth20Service.java @@ -1,261 +1,217 @@ -package com.github.scribejava.core.oauth; - -import com.github.scribejava.core.services.Base64Encoder; -import com.ning.http.client.ProxyServer; -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.concurrent.Future; -import com.github.scribejava.core.builder.api.DefaultApi20; -import com.github.scribejava.core.model.AbstractRequest; -import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuth2Authorization; -import com.github.scribejava.core.model.OAuthAsyncRequestCallback; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.OAuthRequest; -import com.github.scribejava.core.model.OAuthRequestAsync; -import java.util.Map; - -public class OAuth20Service extends OAuthService { - - private static final String VERSION = "2.0"; - private final DefaultApi20 api; - - /** - * Default constructor - * - * @param api - * OAuth2.0 api information - * @param config - * OAuth 2.0 configuration param object - */ - public OAuth20Service(DefaultApi20 api, OAuthConfig config) { - super(config); - this.api = api; - } - - // sync version, protected to facilitate mocking - protected OAuth2AccessToken sendAccessTokenRequestSync(OAuthRequest request) { - return api.getAccessTokenExtractor().extract(request.send().getBody()); - } - - // async version, protected to facilitate mocking - protected Future sendAccessTokenRequestAsync(OAuthRequestAsync request, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - - - return request.sendAsync(callback, new OAuthRequestAsync.ResponseConverter() { - @Override - public OAuth2AccessToken convert(com.ning.http.client.Response response) throws IOException { - return getApi().getAccessTokenExtractor() - .extract(OAuthRequestAsync.RESPONSE_CONVERTER.convert(response).getBody()); - } - }, proxyServer); - } - - public final OAuth2AccessToken getAccessToken(String code) { - final OAuthRequest request = createAccessTokenRequest(code, - new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestSync(request); - } - - /** - * Start the request to retrieve the access token. The optionally provided - * callback will be called with the Token when it is available. - * - * @param code - * code - * @param callback - * optional callback - * @return Future - */ - public final Future getAccessTokenAsync(String code, - OAuthAsyncRequestCallback callback) { - return getAccessTokenAsync(code, callback, null); - } - - public final Future getAccessTokenAsync(String code, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - final OAuthRequestAsync request = createAccessTokenRequest(code, - new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestAsync(request, callback, proxyServer); - } - - protected T createAccessTokenRequest(String code, T request) { - final OAuthConfig config = getConfig(); - request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); - request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); - request.addParameter(OAuthConstants.CODE, code); - request.addParameter(OAuthConstants.REDIRECT_URI, config.getCallback()); - if (config.hasScope()) { - request.addParameter(OAuthConstants.SCOPE, config.getScope()); - } - if (config.hasGrantType()) { - request.addParameter(OAuthConstants.GRANT_TYPE, config.getGrantType()); - } - - int index = request.getSanitizedUrl().indexOf("http://www.oschina.net"); - if (index > -1) { - request.addHeader("User-Agent", - "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"); - } - return request; - } - - public final OAuth2AccessToken refreshAccessToken(String refreshToken) { - final OAuthRequest request = createRefreshTokenRequest(refreshToken, - new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestSync(request); - } - - public final Future refreshAccessTokenAsync(String refreshToken, - OAuthAsyncRequestCallback callback) { - return refreshAccessTokenAsync(refreshToken, callback, null); - } - - public final Future refreshAccessTokenAsync(String refreshToken, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - final OAuthRequestAsync request = createRefreshTokenRequest(refreshToken, - new OAuthRequestAsync(api.getAccessTokenVerb(), api.getRefreshTokenEndpoint(), this)); - - return sendAccessTokenRequestAsync(request, callback, proxyServer); - } - - protected T createRefreshTokenRequest(String refreshToken, T request) { - if (refreshToken == null || refreshToken.isEmpty()) { - throw new IllegalArgumentException("The refreshToken cannot be null or empty"); - } - final OAuthConfig config = getConfig(); - request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); - request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); - request.addParameter(OAuthConstants.REFRESH_TOKEN, refreshToken); - request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.REFRESH_TOKEN); - return request; - } - - /** - * Request Access Token Password Grant sync version - * - * @param uname - * User name - * @param password - * User password - * @return OAuth2AccessToken - */ - public final OAuth2AccessToken getAccessTokenPasswordGrant(String uname, String password) { - final OAuthRequest request = createAccessTokenPasswordGrantRequest(uname, password, - new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestSync(request); - } - - /** - * Request Access Token Password Grant async version - * - * @param uname - * User name - * @param password - * User password - * @param callback - * Optional callback - * @return Future - */ - public final Future getAccessTokenPasswordGrantAsync(String uname, String password, - OAuthAsyncRequestCallback callback) { - return getAccessTokenPasswordGrantAsync(uname, password, callback, null); - } - - public final Future getAccessTokenPasswordGrantAsync(String uname, String password, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - final OAuthRequestAsync request = createAccessTokenPasswordGrantRequest(uname, password, - new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - - return sendAccessTokenRequestAsync(request, callback, proxyServer); - } - - protected T createAccessTokenPasswordGrantRequest(String username, String password, - T request) { - final OAuthConfig config = getConfig(); - request.addParameter(OAuthConstants.USERNAME, username); - request.addParameter(OAuthConstants.PASSWORD, password); - - if (config.hasScope()) { - request.addParameter(OAuthConstants.SCOPE, config.getScope()); - } - - request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.PASSWORD); - - request.addHeader(OAuthConstants.HEADER, OAuthConstants.BASIC + " " + Base64Encoder.getInstance().encode( - String.format("%s:%s", config.getApiKey(), config.getApiSecret()).getBytes(Charset.forName("UTF-8")))); - - return request; - } - - /** - * {@inheritDoc} - */ - @Override - public String getVersion() { - return VERSION; - } - - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { - request.addQuerystringParameter(OAuthConstants.ACCESS_TOKEN, accessToken.getAccessToken()); - } - - /** - * Returns the URL where you should redirect your users to authenticate your - * application. - * - * @return the URL where you should redirect your users - */ - public final String getAuthorizationUrl() { - return getAuthorizationUrl(null); - } - - - public final String getOauth2TokenUrl(String code) { - final OAuthRequest request = createAccessTokenRequest(code, - new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - return request.getCompleteUrl(); - - } - - /** - * Returns the URL where you should redirect your users to authenticate your - * application. - * - * @param additionalParams - * any additional GET params to add to the URL - * @return the URL where you should redirect your users - */ - public String getAuthorizationUrl(Map additionalParams) { - return api.getAuthorizationUrl(getConfig(), additionalParams); - } - - public DefaultApi20 getApi() { - return api; - } - - public OAuth2Authorization extractAuthorization(String redirectLocation) { - final OAuth2Authorization authorization = new OAuth2Authorization(); - for (String param : redirectLocation.substring(redirectLocation.indexOf('?') + 1).split("&")) { - final String[] keyValue = param.split("="); - if (keyValue.length == 2) { - switch (keyValue[0]) { - case "code": - authorization.setCode(keyValue[1]); - break; - case "state": - authorization.setState(keyValue[1]); - break; - default: // just ignore any other param; - } - } - } - return authorization; - } -} +package com.github.scribejava.core.oauth; + +import com.github.scribejava.core.services.Base64Encoder; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.concurrent.Future; +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.model.AbstractRequest; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuth2Authorization; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.OAuthRequestAsync; +import com.github.scribejava.core.model.Response; +import java.util.Map; + +public class OAuth20Service extends OAuthService { + + private static final String VERSION = "2.0"; + private final DefaultApi20 api; + + /** + * Default constructor + * + * @param api OAuth2.0 api information + * @param config OAuth 2.0 configuration param object + */ + public OAuth20Service(DefaultApi20 api, OAuthConfig config) { + super(config); + this.api = api; + } + + //sync version, protected to facilitate mocking + protected OAuth2AccessToken sendAccessTokenRequestSync(OAuthRequest request) throws IOException { + return api.getAccessTokenExtractor().extract(request.send().getBody()); + } + + //async version, protected to facilitate mocking + protected Future sendAccessTokenRequestAsync(OAuthRequestAsync request, + OAuthAsyncRequestCallback callback) { + + return request.sendAsync(callback, new OAuthRequestAsync.ResponseConverter() { + @Override + public OAuth2AccessToken convert(Response response) throws IOException { + return getApi().getAccessTokenExtractor().extract(response.getBody()); + } + }); + } + + public final OAuth2AccessToken getAccessToken(String code) throws IOException { + final OAuthRequest request = createAccessTokenRequest(code, + new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestSync(request); + } + + /** + * Start the request to retrieve the access token. The optionally provided callback will be called with the Token + * when it is available. + * + * @param code code + * @param callback optional callback + * @return Future + */ + public final Future getAccessTokenAsync(String code, + OAuthAsyncRequestCallback callback) { + final OAuthRequestAsync request = createAccessTokenRequest(code, + new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestAsync(request, callback); + } + + protected T createAccessTokenRequest(String code, T request) { + final OAuthConfig config = getConfig(); + request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); + request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); + request.addParameter(OAuthConstants.CODE, code); + request.addParameter(OAuthConstants.REDIRECT_URI, config.getCallback()); + final String scope = config.getScope(); + if (scope != null) { + request.addParameter(OAuthConstants.SCOPE, scope); + } + request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.AUTHORIZATION_CODE); + return request; + } + + public final OAuth2AccessToken refreshAccessToken(String refreshToken) throws IOException { + final OAuthRequest request = createRefreshTokenRequest(refreshToken, + new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestSync(request); + } + + public final Future refreshAccessTokenAsync(String refreshToken, + OAuthAsyncRequestCallback callback) { + final OAuthRequestAsync request = createRefreshTokenRequest(refreshToken, + new OAuthRequestAsync(api.getAccessTokenVerb(), api.getRefreshTokenEndpoint(), this)); + + return sendAccessTokenRequestAsync(request, callback); + } + + protected T createRefreshTokenRequest(String refreshToken, T request) { + if (refreshToken == null || refreshToken.isEmpty()) { + throw new IllegalArgumentException("The refreshToken cannot be null or empty"); + } + final OAuthConfig config = getConfig(); + request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); + request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); + request.addParameter(OAuthConstants.REFRESH_TOKEN, refreshToken); + request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.REFRESH_TOKEN); + return request; + } + + public final OAuth2AccessToken getAccessTokenPasswordGrant(String uname, String password) throws IOException { + final OAuthRequest request = createAccessTokenPasswordGrantRequest(uname, password, + new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestSync(request); + } + + /** + * Request Access Token Password Grant async version + * + * @param uname User name + * @param password User password + * @param callback Optional callback + * @return Future + */ + public final Future getAccessTokenPasswordGrantAsync(String uname, String password, + OAuthAsyncRequestCallback callback) { + final OAuthRequestAsync request = createAccessTokenPasswordGrantRequest(uname, password, + new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); + + return sendAccessTokenRequestAsync(request, callback); + } + + protected T createAccessTokenPasswordGrantRequest(String username, String password, + T request) { + final OAuthConfig config = getConfig(); + request.addParameter(OAuthConstants.USERNAME, username); + request.addParameter(OAuthConstants.PASSWORD, password); + + final String scope = config.getScope(); + if (scope != null) { + request.addParameter(OAuthConstants.SCOPE, scope); + } + + request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.PASSWORD); + + final String apiKey = config.getApiKey(); + final String apiSecret = config.getApiSecret(); + if (apiKey != null && apiSecret != null) { + request.addHeader(OAuthConstants.HEADER, + OAuthConstants.BASIC + ' ' + + Base64Encoder.getInstance() + .encode(String.format("%s:%s", apiKey, apiSecret).getBytes(Charset.forName("UTF-8")))); + } + + return request; + } + + /** + * {@inheritDoc} + */ + @Override + public String getVersion() { + return VERSION; + } + + public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { + request.addQuerystringParameter(OAuthConstants.ACCESS_TOKEN, accessToken.getAccessToken()); + } + + /** + * Returns the URL where you should redirect your users to authenticate your application. + * + * @return the URL where you should redirect your users + */ + public final String getAuthorizationUrl() { + return getAuthorizationUrl(null); + } + + /** + * Returns the URL where you should redirect your users to authenticate your application. + * + * @param additionalParams any additional GET params to add to the URL + * @return the URL where you should redirect your users + */ + public String getAuthorizationUrl(Map additionalParams) { + return api.getAuthorizationUrl(getConfig(), additionalParams); + } + + public DefaultApi20 getApi() { + return api; + } + + public OAuth2Authorization extractAuthorization(String redirectLocation) { + final OAuth2Authorization authorization = new OAuth2Authorization(); + for (String param : redirectLocation.substring(redirectLocation.indexOf('?') + 1).split("&")) { + final String[] keyValue = param.split("="); + if (keyValue.length == 2) { + switch (keyValue[0]) { + case "code": + authorization.setCode(keyValue[1]); + break; + case "state": + authorization.setState(keyValue[1]); + break; + default: //just ignore any other param; + } + } + } + return authorization; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuthService.java b/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuthService.java index 47b40b497..05c8ecac2 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuthService.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuthService.java @@ -1,173 +1,173 @@ -package com.github.scribejava.core.oauth; - -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.model.AbstractRequest; -import static com.github.scribejava.core.model.AbstractRequest.DEFAULT_CONTENT_TYPE; -import com.github.scribejava.core.model.ForceTypeOfHttpRequest; -import com.github.scribejava.core.model.OAuthAsyncRequestCallback; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.OAuthRequestAsync; -import com.github.scribejava.core.model.ScribeJavaConfig; -import com.github.scribejava.core.model.Verb; -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.Future; - -/** - * The main ScribeJava object. - * - * A facade responsible for the retrieval of request and access tokens and for the signing of HTTP requests. - */ -public abstract class OAuthService { - - private final OAuthConfig config; - private final com.ning.http.client.AsyncHttpClient ningAsyncHttpClient; - private final org.asynchttpclient.AsyncHttpClient ahcAsyncHttpClient; - - public OAuthService(OAuthConfig config) { - this.config = config; - final ForceTypeOfHttpRequest forceTypeOfHttpRequest = ScribeJavaConfig.getForceTypeOfHttpRequests(); - final com.ning.http.client.AsyncHttpClientConfig ningConfig = config.getNingAsyncHttpClientConfig(); - final org.asynchttpclient.AsyncHttpClientConfig ahcConfig = config.getAhcAsyncHttpClientConfig(); - - if (ningConfig == null && ahcConfig == null) { - if (ForceTypeOfHttpRequest.FORCE_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - throw new OAuthException("Cannot use sync operations, only async"); - } - if (ForceTypeOfHttpRequest.PREFER_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - config.log("Cannot use sync operations, only async"); - } - ningAsyncHttpClient = null; - ahcAsyncHttpClient = null; - } else { - if (ForceTypeOfHttpRequest.FORCE_SYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - throw new OAuthException("Cannot use async operations, only sync"); - } - if (ForceTypeOfHttpRequest.PREFER_SYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - config.log("Cannot use async operations, only sync"); - } - - if (ahcConfig == null) { - ningAsyncHttpClient = NingProvider.createClient(config.getNingAsyncHttpProviderClassName(), ningConfig); - ahcAsyncHttpClient = null; - } else { - ahcAsyncHttpClient = AHCProvider.createClient(ahcConfig); - ningAsyncHttpClient = null; - } - } - } - - public void closeAsyncClient() throws IOException { - if (ahcAsyncHttpClient == null) { - ningAsyncHttpClient.close(); - } else { - ahcAsyncHttpClient.close(); - } - } - - public OAuthConfig getConfig() { - return config; - } - - /** - * Returns the OAuth version of the service. - * - * @return OAuth version as string - */ - public abstract String getVersion(); - - public Future executeAsync(Map headers, Verb httpVerb, String completeUrl, - String bodyContents, OAuthAsyncRequestCallback callback, - OAuthRequestAsync.ResponseConverter converter) { - if (ahcAsyncHttpClient == null) { - return NingProvider.ningExecuteAsync(ningAsyncHttpClient, config.getUserAgent(), headers, httpVerb, - completeUrl, bodyContents, callback, converter); - } else { - return AHCProvider.ahcExecuteAsync(ahcAsyncHttpClient, config.getUserAgent(), headers, httpVerb, - completeUrl, bodyContents, callback, converter); - } - } - - private static class NingProvider { - - private static com.ning.http.client.AsyncHttpClient createClient(String ningAsyncHttpProviderClassName, - com.ning.http.client.AsyncHttpClientConfig ningConfig) { - return ningAsyncHttpProviderClassName == null - ? new com.ning.http.client.AsyncHttpClient(ningConfig) - : new com.ning.http.client.AsyncHttpClient(ningAsyncHttpProviderClassName, ningConfig); - } - - private static Future ningExecuteAsync(com.ning.http.client.AsyncHttpClient ningAsyncHttpClient, - String userAgent, Map headers, Verb httpVerb, String completeUrl, String bodyContents, - OAuthAsyncRequestCallback callback, OAuthRequestAsync.ResponseConverter converter) { - final com.ning.http.client.AsyncHttpClient.BoundRequestBuilder boundRequestBuilder; - switch (httpVerb) { - case GET: - boundRequestBuilder = ningAsyncHttpClient.prepareGet(completeUrl); - break; - case POST: - com.ning.http.client.AsyncHttpClient.BoundRequestBuilder requestBuilder - = ningAsyncHttpClient.preparePost(completeUrl); - if (!headers.containsKey(AbstractRequest.CONTENT_TYPE)) { - requestBuilder = requestBuilder.addHeader(AbstractRequest.CONTENT_TYPE, DEFAULT_CONTENT_TYPE); - } - boundRequestBuilder = requestBuilder.setBody(bodyContents); - break; - default: - throw new IllegalArgumentException("message build error: unknown verb type"); - } - - for (Map.Entry header : headers.entrySet()) { - boundRequestBuilder.addHeader(header.getKey(), header.getValue()); - } - if (userAgent != null) { - boundRequestBuilder.setHeader(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent); - } - - return boundRequestBuilder - .execute(new com.github.scribejava.core.async.ning.OAuthAsyncCompletionHandler<>( - callback, converter)); - } - } - - private static class AHCProvider { - - private static org.asynchttpclient.AsyncHttpClient createClient( - org.asynchttpclient.AsyncHttpClientConfig ahcConfig) { - return new org.asynchttpclient.DefaultAsyncHttpClient(ahcConfig); - } - - private static Future ahcExecuteAsync(org.asynchttpclient.AsyncHttpClient ahcAsyncHttpClient, - String userAgent, Map headers, Verb httpVerb, String completeUrl, String bodyContents, - OAuthAsyncRequestCallback callback, OAuthRequestAsync.ResponseConverter converter) { - final org.asynchttpclient.BoundRequestBuilder boundRequestBuilder; - switch (httpVerb) { - case GET: - boundRequestBuilder = ahcAsyncHttpClient.prepareGet(completeUrl); - break; - case POST: - org.asynchttpclient.BoundRequestBuilder requestBuilder - = ahcAsyncHttpClient.preparePost(completeUrl); - if (!headers.containsKey(AbstractRequest.CONTENT_TYPE)) { - requestBuilder = requestBuilder.addHeader(AbstractRequest.CONTENT_TYPE, DEFAULT_CONTENT_TYPE); - } - boundRequestBuilder = requestBuilder.setBody(bodyContents); - break; - default: - throw new IllegalArgumentException("message build error: unknown verb type"); - } - - for (Map.Entry header : headers.entrySet()) { - boundRequestBuilder.addHeader(header.getKey(), header.getValue()); - } - if (userAgent != null) { - boundRequestBuilder.setHeader(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent); - } - - return boundRequestBuilder - .execute(new com.github.scribejava.core.async.ahc.OAuthAsyncCompletionHandler<>( - callback, converter)); - } - } -} +package com.github.scribejava.core.oauth; + +import com.github.scribejava.core.exceptions.OAuthException; +import com.github.scribejava.core.model.AbstractRequest; +import static com.github.scribejava.core.model.AbstractRequest.DEFAULT_CONTENT_TYPE; +import com.github.scribejava.core.model.ForceTypeOfHttpRequest; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.OAuthRequestAsync; +import com.github.scribejava.core.model.ScribeJavaConfig; +import com.github.scribejava.core.model.Verb; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.Future; + +/** + * The main ScribeJava object. + * + * A facade responsible for the retrieval of request and access tokens and for the signing of HTTP requests. + */ +public abstract class OAuthService { + + private final OAuthConfig config; + private final com.ning.http.client.AsyncHttpClient ningAsyncHttpClient; + private final org.asynchttpclient.AsyncHttpClient ahcAsyncHttpClient; + + public OAuthService(OAuthConfig config) { + this.config = config; + final ForceTypeOfHttpRequest forceTypeOfHttpRequest = ScribeJavaConfig.getForceTypeOfHttpRequests(); + final com.ning.http.client.AsyncHttpClientConfig ningConfig = config.getNingAsyncHttpClientConfig(); + final org.asynchttpclient.AsyncHttpClientConfig ahcConfig = config.getAhcAsyncHttpClientConfig(); + + if (ningConfig == null && ahcConfig == null) { + if (ForceTypeOfHttpRequest.FORCE_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { + throw new OAuthException("Cannot use sync operations, only async"); + } + if (ForceTypeOfHttpRequest.PREFER_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { + config.log("Cannot use sync operations, only async"); + } + ningAsyncHttpClient = null; + ahcAsyncHttpClient = null; + } else { + if (ForceTypeOfHttpRequest.FORCE_SYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { + throw new OAuthException("Cannot use async operations, only sync"); + } + if (ForceTypeOfHttpRequest.PREFER_SYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { + config.log("Cannot use async operations, only sync"); + } + + if (ahcConfig == null) { + ningAsyncHttpClient = NingProvider.createClient(config.getNingAsyncHttpProviderClassName(), ningConfig); + ahcAsyncHttpClient = null; + } else { + ahcAsyncHttpClient = AHCProvider.createClient(ahcConfig); + ningAsyncHttpClient = null; + } + } + } + + public void closeAsyncClient() throws IOException { + if (ahcAsyncHttpClient == null) { + ningAsyncHttpClient.close(); + } else { + ahcAsyncHttpClient.close(); + } + } + + public OAuthConfig getConfig() { + return config; + } + + /** + * Returns the OAuth version of the service. + * + * @return OAuth version as string + */ + public abstract String getVersion(); + + public Future executeAsync(Map headers, Verb httpVerb, String completeUrl, + String bodyContents, OAuthAsyncRequestCallback callback, + OAuthRequestAsync.ResponseConverter converter) { + if (ahcAsyncHttpClient == null) { + return NingProvider.ningExecuteAsync(ningAsyncHttpClient, config.getUserAgent(), headers, httpVerb, + completeUrl, bodyContents, callback, converter); + } else { + return AHCProvider.ahcExecuteAsync(ahcAsyncHttpClient, config.getUserAgent(), headers, httpVerb, + completeUrl, bodyContents, callback, converter); + } + } + + private static class NingProvider { + + private static com.ning.http.client.AsyncHttpClient createClient(String ningAsyncHttpProviderClassName, + com.ning.http.client.AsyncHttpClientConfig ningConfig) { + return ningAsyncHttpProviderClassName == null + ? new com.ning.http.client.AsyncHttpClient(ningConfig) + : new com.ning.http.client.AsyncHttpClient(ningAsyncHttpProviderClassName, ningConfig); + } + + private static Future ningExecuteAsync(com.ning.http.client.AsyncHttpClient ningAsyncHttpClient, + String userAgent, Map headers, Verb httpVerb, String completeUrl, String bodyContents, + OAuthAsyncRequestCallback callback, OAuthRequestAsync.ResponseConverter converter) { + final com.ning.http.client.AsyncHttpClient.BoundRequestBuilder boundRequestBuilder; + switch (httpVerb) { + case GET: + boundRequestBuilder = ningAsyncHttpClient.prepareGet(completeUrl); + break; + case POST: + com.ning.http.client.AsyncHttpClient.BoundRequestBuilder requestBuilder + = ningAsyncHttpClient.preparePost(completeUrl); + if (!headers.containsKey(AbstractRequest.CONTENT_TYPE)) { + requestBuilder = requestBuilder.addHeader(AbstractRequest.CONTENT_TYPE, DEFAULT_CONTENT_TYPE); + } + boundRequestBuilder = requestBuilder.setBody(bodyContents); + break; + default: + throw new IllegalArgumentException("message build error: unknown verb type"); + } + + for (Map.Entry header : headers.entrySet()) { + boundRequestBuilder.addHeader(header.getKey(), header.getValue()); + } + if (userAgent != null) { + boundRequestBuilder.setHeader(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent); + } + + return boundRequestBuilder + .execute(new com.github.scribejava.core.async.ning.OAuthAsyncCompletionHandler<>( + callback, converter)); + } + } + + private static class AHCProvider { + + private static org.asynchttpclient.AsyncHttpClient createClient( + org.asynchttpclient.AsyncHttpClientConfig ahcConfig) { + return new org.asynchttpclient.DefaultAsyncHttpClient(ahcConfig); + } + + private static Future ahcExecuteAsync(org.asynchttpclient.AsyncHttpClient ahcAsyncHttpClient, + String userAgent, Map headers, Verb httpVerb, String completeUrl, String bodyContents, + OAuthAsyncRequestCallback callback, OAuthRequestAsync.ResponseConverter converter) { + final org.asynchttpclient.BoundRequestBuilder boundRequestBuilder; + switch (httpVerb) { + case GET: + boundRequestBuilder = ahcAsyncHttpClient.prepareGet(completeUrl); + break; + case POST: + org.asynchttpclient.BoundRequestBuilder requestBuilder + = ahcAsyncHttpClient.preparePost(completeUrl); + if (!headers.containsKey(AbstractRequest.CONTENT_TYPE)) { + requestBuilder = requestBuilder.addHeader(AbstractRequest.CONTENT_TYPE, DEFAULT_CONTENT_TYPE); + } + boundRequestBuilder = requestBuilder.setBody(bodyContents); + break; + default: + throw new IllegalArgumentException("message build error: unknown verb type"); + } + + for (Map.Entry header : headers.entrySet()) { + boundRequestBuilder.addHeader(header.getKey(), header.getValue()); + } + if (userAgent != null) { + boundRequestBuilder.setHeader(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent); + } + + return boundRequestBuilder + .execute(new com.github.scribejava.core.async.ahc.OAuthAsyncCompletionHandler<>( + callback, converter)); + } + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/utils/StreamUtils.java b/scribejava-core/src/main/java/com/github/scribejava/core/utils/StreamUtils.java index 7a86318d2..e17437c94 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/utils/StreamUtils.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/utils/StreamUtils.java @@ -1,49 +1,49 @@ -package com.github.scribejava.core.utils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.zip.GZIPInputStream; - -/** - * Utils to deal with Streams. - */ -public abstract class StreamUtils { - - /** - * Returns the stream contents as an UTF-8 encoded string - * - * @param is input stream - * @return string contents - * @throws java.io.IOException in any. SocketTimeout in example - */ - public static String getStreamContents(InputStream is) throws IOException { - Preconditions.checkNotNull(is, "Cannot get String from a null object"); - final char[] buffer = new char[0x10000]; - final StringBuilder out = new StringBuilder(); - try (Reader in = new InputStreamReader(is, "UTF-8")) { - int read; - do { - read = in.read(buffer, 0, buffer.length); - if (read > 0) { - out.append(buffer, 0, read); - } - } while (read >= 0); - } - return out.toString(); - } - - /** - * Return String content from a gzip stream - * - * @param is input stream - * @return string contents - * @throws java.io.IOException in any. SocketTimeout in example - */ - public static String getGzipStreamContents(InputStream is) throws IOException { - Preconditions.checkNotNull(is, "Cannot get String from a null object"); - final GZIPInputStream gis = new GZIPInputStream(is); - return getStreamContents(gis); - } -} +package com.github.scribejava.core.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.zip.GZIPInputStream; + +/** + * Utils to deal with Streams. + */ +public abstract class StreamUtils { + + /** + * Returns the stream contents as an UTF-8 encoded string + * + * @param is input stream + * @return string contents + * @throws java.io.IOException in any. SocketTimeout in example + */ + public static String getStreamContents(InputStream is) throws IOException { + Preconditions.checkNotNull(is, "Cannot get String from a null object"); + final char[] buffer = new char[0x10000]; + final StringBuilder out = new StringBuilder(); + try (Reader in = new InputStreamReader(is, "UTF-8")) { + int read; + do { + read = in.read(buffer, 0, buffer.length); + if (read > 0) { + out.append(buffer, 0, read); + } + } while (read >= 0); + } + return out.toString(); + } + + /** + * Return String content from a gzip stream + * + * @param is input stream + * @return string contents + * @throws java.io.IOException in any. SocketTimeout in example + */ + public static String getGzipStreamContents(InputStream is) throws IOException { + Preconditions.checkNotNull(is, "Cannot get String from a null object"); + final GZIPInputStream gis = new GZIPInputStream(is); + return getStreamContents(gis); + } +} From bc7927e4d464667e2d323625618c2381b4e3308a Mon Sep 17 00:00:00 2001 From: "ada.young" Date: Fri, 17 Jun 2016 15:06:37 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/github/scribejava/apis/WeiXinApi.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java index bc283cb00..018df8b11 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/WeiXinApi.java @@ -14,7 +14,6 @@ public class WeiXinApi extends DefaultApi20 { - private static final String AUTHORIZE_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s"; protected WeiXinApi() { } @@ -51,6 +50,6 @@ public OAuth20Service createService(OAuthConfig config) { @Override protected String getAuthorizationBaseUrl() { // TODO Auto-generated method stub - return "https://graph.qq.com/oauth2.0/authorize"; + return "https://open.weixin.qq.com/connect/qrconnect"; } } From ef347e3e2fc785ae13088dc8805e8d36b07a2ea1 Mon Sep 17 00:00:00 2001 From: "ada.young" Date: Fri, 17 Jun 2016 15:07:35 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 235 +++++++++++++++++++++++++++--------------------------- 1 file changed, 117 insertions(+), 118 deletions(-) diff --git a/README.md b/README.md index 65ce9184c..75addead1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -<<<<<<< HEAD # Welcome to the home of ScribeJava, the simple OAuth Java lib! # Why use ScribeJava? @@ -132,120 +131,120 @@ If you have a useful fork that should be listed there please contact us .responseType("code").build(OschinaApi.instance()); System.out.println(service.getAuthorizationUrl()); - -======= -# Welcome to the home of ScribeJava, the simple OAuth Java lib! - -# Why use ScribeJava? - -### Dead Simple - -Who said OAuth/OAuth2 was difficult? Configuring ScribeJava is __so easy your grandma can do it__! check it out: - -```java -OAuthService service = new ServiceBuilder() - .apiKey(YOUR_API_KEY) - .apiSecret(YOUR_API_SECRET) - .build(LinkedInApi20.instance()); -``` - -That **single line** (added newlines for readability) is the only thing you need to configure ScribeJava with LinkedIn's OAuth API for example. - -### Threadsafe - -Hit ScribeJava as hard and with many threads as you like. - -### Async - -You can use ning async http client out-of-box, just use ServiceBuilderAsync - -### Supports all major 1.0a and 2.0 OAuth APIs out-of-the-box - -* AWeber (http://www.aweber.com/) -* Digg (http://digg.com/) -* Доктор на работе (http://www.doktornarabote.ru/) -* Facebook (https://www.facebook.com/) -* Flickr (https://www.flickr.com/) -* Foursquare (https://foursquare.com/) -* Freelancer (https://www.freelancer.com/) -* Genius (http://genius.com/) -* GitHub (https://github.com/) -* Google (https://www.google.ru/) -* HeadHunter ХэдХантер (https://hh.ru/) -* Imgur (http://imgur.com/) -* Kaixin 开心网 (http://www.kaixin001.com/) -* LinkedIn (https://www.linkedin.com/) -* Microsoft Live (https://login.live.com/) -* Mail.Ru (https://mail.ru/) -* Meetup (http://www.meetup.com/) -* NetEase (http://www.163.com/) -* Odnoklassniki Одноклассники (http://ok.ru/) -* Pinterest (https://www.pinterest.com/) -* 500px (https://500px.com/) -* Renren (http://renren.com/) -* Salesforce (https://www.salesforce.com/) -* Sina (http://www.sina.com.cn/ http://weibo.com/login.php) -* Skyrock (http://skyrock.com/) -* sohu 搜狐 (http://www.sohu.com/) -* StackExchange (http://stackexchange.com/) -* Trello (https://trello.com/) -* Tumblr (https://www.tumblr.com/) -* TUT.BY (http://www.tut.by/) -* Twitter (https://twitter.com/) -* Viadeo (http://viadeo.com/) -* VK ВКонтакте (http://vk.com/) -* XING (https://www.xing.com/) -* Yahoo (https://www.yahoo.com/) -* Misfit (http://misfit.com/) -* check the [examples folder](https://github.com/scribejava/scribejava/tree/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples) - -### Small and modular - -ScribeJava's code is small (about 1k LOC) and simple to understand. No smart-ass or "clever" hacks here. -You can use only 'core' or 'with apis' maven modules - -### Android-Ready - -Works out of the box with android(TM) applications. - -### Stable & bulletproof - -Good test coverage to keep you safe from harm. - -When something bad actually happens, ScribeJava's meaningful error messages will tell you exactly what went wrong, when and where. - -### Pull it from Maven Central! - -You can pull ScribeJava from the central maven repository, just add these to your __pom.xml__ file: - -```xml - - com.github.scribejava - scribejava-apis - 2.7.3 - -``` - -And in case you need just core classes (that's it, without any external API (FB, VK, GitHub, Google etc) specific code), you could pull just 'core' artifact. -```xml - - com.github.scribejava - scribejava-core - 2.7.3 - -``` - -## Getting started in less than 2 minutes - -Check the [Getting Started](https://github.com/scribejava/scribejava/wiki/getting-started) page and start rocking! Please Read the [FAQ](https://github.com/scribejava/scribejava/wiki/faq) before creating an issue :) - -Also, remember to read the [fantastic tutorial](http://akoskm.github.io/2015/07/31/twitter-sign-in-for-web-apps.html) that [@akoskm](https://twitter.com/akoskm) wrote to easily integrate a server side app with an API (twitter in this case). - -## Questions? - -Feel free to drop us an email or create issue right here on github.com - -## Forks - -If you have a useful fork that should be listed there please contact us ->>>>>>> branch 'master' of https://github.com/scribejava/scribejava.git + +======= +# Welcome to the home of ScribeJava, the simple OAuth Java lib! + +# Why use ScribeJava? + +### Dead Simple + +Who said OAuth/OAuth2 was difficult? Configuring ScribeJava is __so easy your grandma can do it__! check it out: + +```java +OAuthService service = new ServiceBuilder() + .apiKey(YOUR_API_KEY) + .apiSecret(YOUR_API_SECRET) + .build(LinkedInApi20.instance()); +``` + +That **single line** (added newlines for readability) is the only thing you need to configure ScribeJava with LinkedIn's OAuth API for example. + +### Threadsafe + +Hit ScribeJava as hard and with many threads as you like. + +### Async + +You can use ning async http client out-of-box, just use ServiceBuilderAsync + +### Supports all major 1.0a and 2.0 OAuth APIs out-of-the-box + +* AWeber (http://www.aweber.com/) +* Digg (http://digg.com/) +* Доктор на работе (http://www.doktornarabote.ru/) +* Facebook (https://www.facebook.com/) +* Flickr (https://www.flickr.com/) +* Foursquare (https://foursquare.com/) +* Freelancer (https://www.freelancer.com/) +* Genius (http://genius.com/) +* GitHub (https://github.com/) +* Google (https://www.google.ru/) +* HeadHunter ХэдХантер (https://hh.ru/) +* Imgur (http://imgur.com/) +* Kaixin 开心网 (http://www.kaixin001.com/) +* LinkedIn (https://www.linkedin.com/) +* Microsoft Live (https://login.live.com/) +* Mail.Ru (https://mail.ru/) +* Meetup (http://www.meetup.com/) +* NetEase (http://www.163.com/) +* Odnoklassniki Одноклассники (http://ok.ru/) +* Pinterest (https://www.pinterest.com/) +* 500px (https://500px.com/) +* Renren (http://renren.com/) +* Salesforce (https://www.salesforce.com/) +* Sina (http://www.sina.com.cn/ http://weibo.com/login.php) +* Skyrock (http://skyrock.com/) +* sohu 搜狐 (http://www.sohu.com/) +* StackExchange (http://stackexchange.com/) +* Trello (https://trello.com/) +* Tumblr (https://www.tumblr.com/) +* TUT.BY (http://www.tut.by/) +* Twitter (https://twitter.com/) +* Viadeo (http://viadeo.com/) +* VK ВКонтакте (http://vk.com/) +* XING (https://www.xing.com/) +* Yahoo (https://www.yahoo.com/) +* Misfit (http://misfit.com/) +* check the [examples folder](https://github.com/scribejava/scribejava/tree/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples) + +### Small and modular + +ScribeJava's code is small (about 1k LOC) and simple to understand. No smart-ass or "clever" hacks here. +You can use only 'core' or 'with apis' maven modules + +### Android-Ready + +Works out of the box with android(TM) applications. + +### Stable & bulletproof + +Good test coverage to keep you safe from harm. + +When something bad actually happens, ScribeJava's meaningful error messages will tell you exactly what went wrong, when and where. + +### Pull it from Maven Central! + +You can pull ScribeJava from the central maven repository, just add these to your __pom.xml__ file: + +```xml + + com.github.scribejava + scribejava-apis + 2.7.3 + +``` + +And in case you need just core classes (that's it, without any external API (FB, VK, GitHub, Google etc) specific code), you could pull just 'core' artifact. +```xml + + com.github.scribejava + scribejava-core + 2.7.3 + +``` + +## Getting started in less than 2 minutes + +Check the [Getting Started](https://github.com/scribejava/scribejava/wiki/getting-started) page and start rocking! Please Read the [FAQ](https://github.com/scribejava/scribejava/wiki/faq) before creating an issue :) + +Also, remember to read the [fantastic tutorial](http://akoskm.github.io/2015/07/31/twitter-sign-in-for-web-apps.html) that [@akoskm](https://twitter.com/akoskm) wrote to easily integrate a server side app with an API (twitter in this case). + +## Questions? + +Feel free to drop us an email or create issue right here on github.com + +## Forks + +If you have a useful fork that should be listed there please contact us +>>>>>>> branch 'master' of https://github.com/scribejava/scribejava.git