diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..a79954ad5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: java +script: mvn clean package +jdk: + - oraclejdk8 + - oraclejdk7 + - openjdk7 +os: + - linux diff --git a/README.md b/README.md index 59e58dc7f..808dc634e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -# Welcome to the home of ScribeJava, the simple OAuth Java lib! +# Welcome to the home of ScribeJava, the simple OAuth client Java lib! + +[![Build Status](https://travis-ci.org/scribejava/scribejava.svg?branch=master)](https://travis-ci.org/scribejava/scribejava) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.scribejava/scribejava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.scribejava/scribejava) + # Why use ScribeJava? @@ -15,45 +19,63 @@ OAuthService service = new ServiceBuilder() That **single line** (added newlines for readability) is the only thing you need to configure ScribeJava with LinkedIn's OAuth API for example. +Working runnable examples are [here](https://github.com/scribejava/scribejava/tree/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples) + ### Threadsafe Hit ScribeJava as hard and with many threads as you like. -### Async +### Async and other HTTP clients -You can user ning async http client out-of-box, just use ServiceBuilderAsync +ScribeJava support out-of-box several HTTP clients: + * ning async http client 1.9.x (maven module scribejava-httpclient-ning) + * asynchttpclient 2.x (maven module scribejava-httpclient-ahc) + * OkHttp (maven module scribejava-httpclient-okhttp) + + just add corresponding maven modules to your pom ### 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) +* AWeber (http://www.aweber.com/) +* Box (https://www.box.com/) +* Digg (http://digg.com/) +* Доктор на работе (https://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.com/) +* 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/) +* NAVER (http://www.naver.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/) +* The Things Network (v1-staging and v2-preview) (https://www.thethingsnetwork.org/) +* 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 @@ -78,7 +100,7 @@ You can pull ScribeJava from the central maven repository, just add these to you com.github.scribejava scribejava-apis - 2.2.2 + 4.1.1 ``` @@ -87,7 +109,7 @@ And in case you need just core classes (that's it, without any external API (FB, com.github.scribejava scribejava-core - 2.2.2 + 4.1.1 ``` @@ -103,6 +125,4 @@ Feel free to drop us an email or create issue right here on github.com ## Forks -Looking for a ScribeJava variation? check the [Fork List](https://github.com/scribejava/scribejava/wiki/Forks) - If you have a useful fork that should be listed there please contact us diff --git a/changelog b/changelog index 8e7e9690c..a66b68f9a 100644 --- a/changelog +++ b/changelog @@ -1,7 +1,120 @@ [SNAPSHOT] + * LinkedIn use Header to sign OAuth2 requests + * upgrade ServiceBuilder to check apiKey preconditions compile-tim (not run-time) + +[4.1.1] + * omit the client_secret parameter if it is an empty string while refreshing token (thanks to https://github.com/KungfuPancake) + * allow perms to be specified in Flickr Api (read, write, or delete) (thanks to https://github.com/rogerhu) + * OdnoklassnikiService should consider params in a body while signing the request (thanks to https://github.com/MrNeuronix) + * do not open OutputStream for output while sending empty body in HTTP requests in the default JDK Http client + +[4.1.0] + * make client_secret optional in OAuth2 while requesting AccessToken (if set to null, it's not required by OAuth2 specs) + * move OAuth1 SignatureType from ServiceBuilder to API + * add body for PATCH HTTP method + * make addOAuthParams appendSignature methods protected in OAuth10aService (to override them in case of need) (thanks to https://github.com/vivin) + +[4.0.0] + * Remove OAuthRequestAsync, just OAuthRequest. Request should know about sync vs async. Move default Http engine to JDKHttpClient. + * introduce SignatureType for OAuth2.0 to implement Bearer signing for the requests + * switch Google, GitHub, Facebook OAuth2.0 oauth requests signing to more secured recommended variant (GET-param -> header Bearer) + * introduce custom nonstandard Facebook AccessTokenErrorResponse + +[3.4.1] + * Drop deprecated methods + * Move doktornarabote.ru urls to https (thanks to https://github.com/ezibrov) + +[3.4.0] + * uncouple OAuthRequest and Service. OAuthRequest shouldn't know anything about OAuthservice. + You don't need OAuthService to create OAuthRequest anymore. Async request should be sent via OAuthService method. + * add support for byte[] and File (async only) payload in OAuth Requests (thanks to https://github.com/keijohyttinen) + * add support for HTTP verbs (thanks to https://github.com/keijohyttinen) + * add OkHttp http client support (thanks to https://github.com/arcao) + * add default HTTP client configs (to use like 'new ServiceBuilder().httpClientConfig(OkHttpHttpClientConfig.defaultConfig())') + * you can use your own impl of AsyncHttpClient + +[3.3.0] + * update Facebook v2.6 -> v2.8 + * add The Things Network API (v1-staging and v2-preview) (thanks to https://github.com/jpmeijers) + * add Box (thanks to https://github.com/MclaughlinSteve) + * fix: OAuth20Service::refreshAccessToken should use RefreshTokenEndpoint, not AccessTokenEndpoint (thanks to https://github.com/vivin) + * move signRequest method to OAuthService (common for OAuth1 and OAuth2) (thanks to https://github.com/apomelov) + * drop deprecated setConnectionKeepAlive method + +[3.2.0] + * Add Naver API (thanks to chooco) + * handle OAuth2 error response for Issuing an Access Token (thanks to juherr) + +[3.1.0] + * fix OdnoklassnikiServiceImpl signature, params for hash must be sorted in lexicographic order, see http://new.apiok.ru/dev/methods/ + * add posibility to use externally created http client + * make ScribeJava compilable under jdk7 (checkstyle downgraded for jdk 1.7) + * add travis CI (check [oracle|open]jdk7 oraclejdk8) + +[3.0.0] + * create abstract HTTP Client layer to support different HTTP clients as plugins (AHC and Ning support becames maven submodules) + * remove changing global JVM property http.keepAlive, deprecate controlling this property inside of ScribeJava (thanks to wldaunfr and rockihack) + +[2.8.1] + * add Salesforce sandbox API support + +[2.8.0] + * add Salesforce API + * update Linked In API + +[2.7.3] + * FIX: ScribeJava shouldn't require all async http client provider to be on the classpath if using only one of them + +[2.7.2] + * FIX: ScribeJava shouldn't require any async http client provider to be on the classpath (neither ning neither AHC) + +[2.7.1] + * do not hide checked IOException in unchecked IllegalArgumentException + +[2.7.0] + * make http async client implementation be more pluggable + * add async-http-client 2.0 support (thanks to Sai Chandrasekharan https://github.com/saichand) + * add Misfit (http://misfit.com/) API + * implement async version getting Request Token for OAuth 1.0a + +[2.6.0] + * simplify async/sync usages + * add optional "User-Agent" config option to use while making http calls + * refactor usage of grant_type [authorization_code|refresh_token|password|etc] + * add Genius.com API authentication (OAuth2) + * fix GitHub API + * standardize authorization url generation for OAuth2 + * update Facebook to v2.6 + * cleanup: drop old APIs without Examples and with outdated domains + +[2.5.3] + * fix - do not send two Content-Type header in async requests + * improve OK example + +[2.5.2] + * add Google Async Exmaple (with bugfix for it to work) + * add OSGI manifest metadata + * apiSecret is not mandatory parameter in config (to use on client sides and other flows without need of the API secret) + * implement OAuth2 Authorization Response parsing in the OAuth20Service (to extract code and state from url, useful for Android) + * update ok.ru API urls, add 'state' support, add refresh token to the example + +[2.4.0] + * APIs 2.0 can define different endpoints for access token and for refresh token (the same urls by default) + * mark Facebook doesn't support refresh token by throwing UnsupportedOperationException + * make JSON Access Token Extractor be the default for OAuth 2.0 (according to RFC 6749) + * drop Google OAuth 1.0 support (OAuth 1.0 was officially deprecated by Google) + * add response_type parameter to the ServiceBuilder/OAuthConfig to use not only "code" for authorization code + * remove Verifier object, we just need Strings, 'code' for OAuth2 and 'oauthVerifier' for OAuth1 + * default HTTP verb for OAuth 2.0 Access Token EndPoint is POST (http://tools.ietf.org/html/rfc6749#section-3.2) + * send missed headers in async version (as in sync) + * support 'password' grant_type for OAuth 2.0 + +[2.3.0] * Stack Exchange authentication via OAuth 2.0 (stackoverflow.com, askubuntu.com, etc.). * Support response in gzip. * differentiate OAuth1 Access token, OAuth 1 Request Token and OAuth 2 Access token, make them conforms RFCs + * OAuth 1 APIs can choose whether to pass empty oauth_token param in requests + * Support refresh tokens for OAuth2 (very thanks to P. Daniel Tyreus https://github.com/pdtyreus) [2.2.2] * make all APIs to be extentable (have protected constructors, useful for testing) diff --git a/pom.xml b/pom.xml index 2a2a7abfe..79f339291 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.github.scribejava scribejava pom - 2.2.3-SNAPSHOT + 4.1.2-SNAPSHOT ScribeJava OAuth Library The best OAuth library out there https://github.com/scribejava/scribejava @@ -17,6 +17,9 @@ scribejava-core scribejava-apis + scribejava-httpclient-ahc + scribejava-httpclient-ning + scribejava-httpclient-okhttp @@ -30,7 +33,8 @@ scm:git:git://github.com/scribejava/scribejava.git scm:git:git@github.com:scribejava/scribejava.git https://github.com/scribejava/scribejava - + HEAD + @@ -44,7 +48,6 @@ +3 - kullfar@jabber.ru kullfar@gmail.com +7-909-677-11-16 @@ -80,6 +83,12 @@ 4.12 test + + com.google.code.gson + gson + 2.8.0 + test + commons-codec commons-codec @@ -87,25 +96,59 @@ compile true - - com.ning - async-http-client - 1.9.32 - provided - - - - org.apache.maven.wagon - wagon-webdav - 1.0-beta-2 - - + + + + org.apache.felix + maven-bundle-plugin + 3.3.0 + + + bundle-manifest + process-classes + + manifest + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.17 + + + com.puppycrawl.tools + checkstyle + 7.7 + + + + + maven-release-plugin + 2.5.3 + + true + + + + maven-compiler-plugin - 3.5 + 3.6.1 UTF-8 1.7 @@ -129,7 +172,7 @@ org.apache.maven.plugins maven-resources-plugin - 2.7 + 3.0.2 UTF-8 @@ -137,7 +180,7 @@ org.apache.maven.plugins maven-source-plugin - 2.4 + 3.0.1 attach-sources @@ -150,7 +193,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.3 + 2.10.4 UTF-8 @@ -166,14 +209,6 @@ org.apache.maven.plugins maven-checkstyle-plugin - 2.17 - - - com.puppycrawl.tools - checkstyle - 6.14.1 - - validate @@ -192,8 +227,32 @@ - + + + jdk-1.7 + + 1.7 + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.17 + + + com.puppycrawl.tools + checkstyle + 6.19 + + + + + + + release-sign-artifacts @@ -222,4 +281,4 @@ - + diff --git a/scribejava-apis/pom.xml b/scribejava-apis/pom.xml index f661a6b4c..b12ba4c48 100644 --- a/scribejava-apis/pom.xml +++ b/scribejava-apis/pom.xml @@ -5,7 +5,7 @@ com.github.scribejava scribejava - 2.2.3-SNAPSHOT + 4.1.2-SNAPSHOT ../pom.xml @@ -20,6 +20,36 @@ scribejava-core ${project.version} + + com.github.scribejava + scribejava-httpclient-ahc + ${project.version} + test + + + com.github.scribejava + scribejava-httpclient-ning + ${project.version} + test + + + com.github.scribejava + scribejava-httpclient-okhttp + ${project.version} + test + + + + + 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/BoxApi20.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/BoxApi20.java new file mode 100644 index 000000000..d21cc39be --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/BoxApi20.java @@ -0,0 +1,37 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; + +/** + * Box.com Api + */ +public class BoxApi20 extends DefaultApi20 { + + + protected BoxApi20() { + } + + private static class InstanceHolder { + private static final BoxApi20 INSTANCE = new BoxApi20(); + } + + public static BoxApi20 instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://api.box.com/oauth2/token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://account.box.com/api/oauth2/authorize"; + } + + @Override + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/ConstantContactApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/ConstantContactApi.java deleted file mode 100644 index a9f0e196c..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/ConstantContactApi.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class ConstantContactApi extends DefaultApi10a { - - private static final String AUTHORIZE_URL - = "https://oauth.constantcontact.com/ws/oauth/confirm_access?oauth_token=%s"; - - protected ConstantContactApi() { - } - - private static class InstanceHolder { - private static final ConstantContactApi INSTANCE = new ConstantContactApi(); - } - - public static ConstantContactApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAccessTokenEndpoint() { - return "https://oauth.constantcontact.com/ws/oauth/access_token"; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZE_URL, requestToken.getToken()); - } - - @Override - public String getRequestTokenEndpoint() { - return "https://oauth.constantcontact.com/ws/oauth/request_token"; - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/ConstantContactApi2.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/ConstantContactApi2.java deleted file mode 100644 index d910e73b9..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/ConstantContactApi2.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.apis.constantcontact.ConstantContactTokenExtractor; - -import com.github.scribejava.core.builder.api.DefaultApi20; -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.utils.OAuthEncoder; - -public class ConstantContactApi2 extends DefaultApi20 { - - private static final String AUTHORIZE_URL - = "https://oauth2.constantcontact.com/oauth2/oauth/siteowner/authorize?client_id=%s&response_type=code" - + "&redirect_uri=%s"; - - protected ConstantContactApi2() { - } - - private static class InstanceHolder { - private static final ConstantContactApi2 INSTANCE = new ConstantContactApi2(); - } - - public static ConstantContactApi2 instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAccessTokenEndpoint() { - return "https://oauth2.constantcontact.com/oauth2/oauth/token?grant_type=" + OAuthConstants.AUTHORIZATION_CODE; - } - - @Override - public String getAuthorizationUrl(OAuthConfig config) { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } - - @Override - public Verb getAccessTokenVerb() { - return Verb.POST; - } - - @Override - public TokenExtractor getAccessTokenExtractor() { - return ConstantContactTokenExtractor.instance(); - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/DoktornaraboteApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/DoktornaraboteApi.java index f937d62bd..1fcac7108 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/DoktornaraboteApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/DoktornaraboteApi.java @@ -1,23 +1,9 @@ package com.github.scribejava.apis; -import com.github.scribejava.apis.service.DoktornaraboteOAuthServiceImpl; import com.github.scribejava.core.builder.api.DefaultApi20; -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.Verb; -import com.github.scribejava.core.oauth.OAuth20Service; -import com.github.scribejava.core.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; public class DoktornaraboteApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "http://auth.doktornarabote.ru/OAuth/Authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s"; - private static final String TOKEN_URL = "http://auth.doktornarabote.ru/OAuth/Token"; - protected DoktornaraboteApi() { } @@ -29,44 +15,13 @@ public static DoktornaraboteApi instance() { return InstanceHolder.INSTANCE; } - @Override - public Verb getAccessTokenVerb() { - return Verb.POST; - } - @Override public String getAccessTokenEndpoint() { - return TOKEN_URL; - } - - @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl( - config.getCallback(), - "Must provide a valid url as callback. Doktornarabote does not support OOB"); - final StringBuilder sb = new StringBuilder( - String.format( - AUTHORIZE_URL, - config.getApiKey(), - OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope()) - ) - ); - - final String state = config.getState(); - if (state != null) { - sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); - } - return sb.toString(); - } - - @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + return "https://auth.doktornarabote.ru/OAuth/Token"; } @Override - public OAuth20Service createService(OAuthConfig config) { - return new DoktornaraboteOAuthServiceImpl(this, config); + protected String getAuthorizationBaseUrl() { + return "https://auth.doktornarabote.ru/OAuth/Authorize"; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/DropBoxApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/DropBoxApi.java deleted file mode 100644 index 99ae6f874..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/DropBoxApi.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class DropBoxApi extends DefaultApi10a { - - protected DropBoxApi() { - } - - private static class InstanceHolder { - private static final DropBoxApi INSTANCE = new DropBoxApi(); - } - - public static DropBoxApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAccessTokenEndpoint() { - return "https://api.dropbox.com/1/oauth/access_token"; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return "https://www.dropbox.com/1/oauth/authorize?oauth_token=" + requestToken.getToken(); - } - - @Override - public String getRequestTokenEndpoint() { - return "https://api.dropbox.com/1/oauth/request_token"; - } - -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/EvernoteApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/EvernoteApi.java deleted file mode 100644 index 0bbd2ac62..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/EvernoteApi.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class EvernoteApi extends DefaultApi10a { - - protected EvernoteApi() { - } - - private static class InstanceHolder { - private static final EvernoteApi INSTANCE = new EvernoteApi(); - } - - public static EvernoteApi instance() { - return InstanceHolder.INSTANCE; - } - - protected String serviceUrl() { - return "https://www.evernote.com"; - } - - @Override - public String getRequestTokenEndpoint() { - return serviceUrl() + "/oauth"; - } - - @Override - public String getAccessTokenEndpoint() { - return serviceUrl() + "/oauth"; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(serviceUrl() + "/OAuth.action?oauth_token=%s", requestToken.getToken()); - } - - /** - * Sandbox endpoint - */ - public static class Sandbox extends EvernoteApi { - - private Sandbox() { - } - - private static class InstanceHolder { - private static final Sandbox INSTANCE = new Sandbox(); - } - - public static Sandbox instance() { - return InstanceHolder.INSTANCE; - } - - @Override - protected String serviceUrl() { - return "https://sandbox.evernote.com"; - } - } - - /** - * Yinxiang Biji endpoint - */ - public static class Yinxiang extends EvernoteApi { - - private Yinxiang() { - } - - private static class InstanceHolder { - private static final Yinxiang INSTANCE = new Yinxiang(); - } - - public static Yinxiang instance() { - return InstanceHolder.INSTANCE; - } - - @Override - protected String serviceUrl() { - return "https://app.yinxiang.com"; - } - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FacebookApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FacebookApi.java index ec0acd245..f761aab03 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/FacebookApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FacebookApi.java @@ -1,27 +1,21 @@ package com.github.scribejava.apis; +import com.github.scribejava.apis.facebook.FacebookAccessTokenJsonExtractor; import com.github.scribejava.core.builder.api.DefaultApi20; -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.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; - -/*** - * Facebook v2.5 API - * +import com.github.scribejava.core.model.Verb; + +/** + * Facebook v2.8 API */ public class FacebookApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://www.facebook.com/v2.5/dialog/oauth?client_id=%s&redirect_uri=%s"; - protected FacebookApi() { } private static class InstanceHolder { + private static final FacebookApi INSTANCE = new FacebookApi(); } @@ -30,29 +24,27 @@ public static FacebookApi instance() { } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public Verb getAccessTokenVerb() { + return Verb.GET; } @Override public String getAccessTokenEndpoint() { - return "https://graph.facebook.com/v2.5/oauth/access_token"; + return "https://graph.facebook.com/v2.8/oauth/access_token"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. Facebook 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)); - } - return sb.toString(); + public String getRefreshTokenEndpoint() { + throw new UnsupportedOperationException("Facebook doesn't support refershing tokens"); + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://www.facebook.com/v2.8/dialog/oauth"; + } + + @Override + public TokenExtractor getAccessTokenExtractor() { + return FacebookAccessTokenJsonExtractor.instance(); } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FlickrApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FlickrApi.java index 0e1db4ea7..f5ecca530 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/FlickrApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FlickrApi.java @@ -10,7 +10,23 @@ */ public class FlickrApi extends DefaultApi10a { + private static final String AUTHORIZE_URL = "https://www.flickr.com/services/oauth/authorize?oauth_token=%s"; + + public enum FlickrPerm { + READ, WRITE, DELETE + }; + + /** + * read, write, or delete (delete includes read/write) + */ + private final String permString; + protected FlickrApi() { + permString = null; + } + + protected FlickrApi(FlickrPerm perm) { + permString = perm.name().toLowerCase(); } private static class InstanceHolder { @@ -21,6 +37,10 @@ public static FlickrApi instance() { return InstanceHolder.INSTANCE; } + public static FlickrApi instance(FlickrPerm perm) { + return perm == null ? instance() : new FlickrApi(perm); + } + /** * {@inheritDoc} */ @@ -34,7 +54,13 @@ public String getAccessTokenEndpoint() { */ @Override public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return "https://www.flickr.com/services/oauth/authorize?oauth_token=" + requestToken.getToken(); + String authUrl = String.format(AUTHORIZE_URL, requestToken.getToken()); + + if (permString != null) { + authUrl += "&perms=" + permString; + } + + return authUrl; } /** diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/Foursquare2Api.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/Foursquare2Api.java index d221dcbac..321554af2 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/Foursquare2Api.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/Foursquare2Api.java @@ -1,19 +1,11 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; +import com.github.scribejava.core.model.Verb; public class Foursquare2Api extends DefaultApi20 { - private static final String AUTHORIZATION_URL - = "https://foursquare.com/oauth2/authenticate?client_id=%s&response_type=code&redirect_uri=%s"; - protected Foursquare2Api() { } @@ -25,20 +17,23 @@ public static Foursquare2Api instance() { return InstanceHolder.INSTANCE; } + @Override + public Verb getAccessTokenVerb() { + return Verb.GET; + } + @Override public String getAccessTokenEndpoint() { - return "https://foursquare.com/oauth2/access_token?grant_type=" + OAuthConstants.AUTHORIZATION_CODE; + return "https://foursquare.com/oauth2/access_token"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. Foursquare2 does not support OOB"); - return String.format(AUTHORIZATION_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + protected String getAuthorizationBaseUrl() { + return "https://foursquare.com/oauth2/authenticate"; } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FreelancerApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FreelancerApi.java index 52fe4cc1f..65b64c04f 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/FreelancerApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FreelancerApi.java @@ -1,6 +1,7 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi10a; +import com.github.scribejava.core.builder.api.OAuth1SignatureType; import com.github.scribejava.core.model.OAuth1RequestToken; import com.github.scribejava.core.model.Verb; @@ -19,6 +20,11 @@ public static FreelancerApi instance() { return InstanceHolder.INSTANCE; } + @Override + public OAuth1SignatureType getSignatureType() { + return OAuth1SignatureType.QueryString; + } + @Override public String getAccessTokenEndpoint() { return "http://api.freelancer.com/RequestAccessToken/requestAccessToken.xml?"; diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/GeniusApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/GeniusApi.java new file mode 100644 index 000000000..03eae859c --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/GeniusApi.java @@ -0,0 +1,28 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.core.builder.api.DefaultApi20; + +public class GeniusApi extends DefaultApi20 { + + protected GeniusApi() { + } + + private static class InstanceHolder { + + private static final GeniusApi INSTANCE = new GeniusApi(); + } + + public static GeniusApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://api.genius.com/oauth/token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://api.genius.com/oauth/authorize"; + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/GetGlueApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/GetGlueApi.java deleted file mode 100644 index 758214390..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/GetGlueApi.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class GetGlueApi extends DefaultApi10a { - - private static final String AUTHORIZE_URL = "http://getglue.com/oauth/authorize?oauth_token=%s"; - private static final String REQUEST_TOKEN_RESOURCE = "https://api.getglue.com/oauth/request_token"; - private static final String ACCESS_TOKEN_RESOURCE = "https://api.getglue.com/oauth/access_token"; - - protected GetGlueApi() { - } - - private static class InstanceHolder { - private static final GetGlueApi INSTANCE = new GetGlueApi(); - } - - public static GetGlueApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAccessTokenEndpoint() { - return ACCESS_TOKEN_RESOURCE; - } - - @Override - public String getRequestTokenEndpoint() { - return REQUEST_TOKEN_RESOURCE; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZE_URL, requestToken.getToken()); - } - -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/GitHubApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/GitHubApi.java index 6d48a107f..ada35c1b3 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/GitHubApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/GitHubApi.java @@ -1,15 +1,13 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; +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.Verb; public class GitHubApi extends DefaultApi20 { - private static final String AUTHORIZE_URL = "https://github.com/login/oauth/authorize?client_id=%s&redirect_uri=%s"; - protected GitHubApi() { } @@ -21,24 +19,23 @@ public static GitHubApi instance() { return InstanceHolder.INSTANCE; } + @Override + public Verb getAccessTokenVerb() { + return Verb.POST; + } + @Override public String getAccessTokenEndpoint() { return "https://github.com/login/oauth/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)); - } - return sb.toString(); + protected String getAuthorizationBaseUrl() { + return "https://github.com/login/oauth/authorize"; + } + + @Override + public TokenExtractor getAccessTokenExtractor() { + return OAuth2AccessTokenExtractor.instance(); } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/GoogleApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/GoogleApi.java deleted file mode 100644 index af8448385..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/GoogleApi.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.model.Verb; - -public class GoogleApi extends DefaultApi10a { - - private static final String AUTHORIZATION_URL - = "https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=%s"; - - protected GoogleApi() { - } - - private static class InstanceHolder { - private static final GoogleApi INSTANCE = new GoogleApi(); - } - - public static GoogleApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAccessTokenEndpoint() { - return "https://www.google.com/accounts/OAuthGetAccessToken"; - } - - @Override - public String getRequestTokenEndpoint() { - return "https://www.google.com/accounts/OAuthGetRequestToken"; - } - - @Override - public Verb getAccessTokenVerb() { - return Verb.GET; - } - - @Override - public Verb getRequestTokenVerb() { - return Verb.GET; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZATION_URL, requestToken.getToken()); - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/GoogleApi20.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/GoogleApi20.java index cde5105a0..157753f6d 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/GoogleApi20.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/GoogleApi20.java @@ -1,21 +1,12 @@ package com.github.scribejava.apis; import com.github.scribejava.apis.google.GoogleJsonTokenExtractor; -import com.github.scribejava.apis.service.GoogleOAuthServiceImpl; import com.github.scribejava.core.builder.api.DefaultApi20; 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; public class GoogleApi20 extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%s&redirect_uri=%s&scope=%s"; - protected GoogleApi20() { } @@ -27,35 +18,18 @@ public static GoogleApi20 instance() { return InstanceHolder.INSTANCE; } - @Override - public Verb getAccessTokenVerb() { - return Verb.POST; - } - @Override public String getAccessTokenEndpoint() { - return "https://accounts.google.com/o/oauth2/token"; + return "https://www.googleapis.com/oauth2/v4/token"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - final StringBuilder sb = new StringBuilder(String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode( - config.getCallback()), OAuthEncoder.encode(config.getScope()))); - - final String state = config.getState(); - if (state != null) { - sb.append('&').append(OAuthConstants.STATE).append('=').append(OAuthEncoder.encode(state)); - } - return sb.toString(); + protected String getAuthorizationBaseUrl() { + return "https://accounts.google.com/o/oauth2/auth"; } @Override public TokenExtractor getAccessTokenExtractor() { return GoogleJsonTokenExtractor.instance(); } - - @Override - public OAuth20Service createService(OAuthConfig config) { - return new GoogleOAuthServiceImpl(this, config); - } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/HHApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/HHApi.java index c0fd8f1e2..2a8a8aa12 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/HHApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/HHApi.java @@ -1,23 +1,9 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.Verb; - -import com.github.scribejava.apis.service.HHOAuthServiceImpl; -import com.github.scribejava.core.extractors.TokenExtractor; -import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.oauth.OAuth20Service; -import com.github.scribejava.core.utils.OAuthEncoder; public class HHApi extends DefaultApi20 { - private static final String AUTHORIZE_URL = "https://hh.ru/oauth/authorize?response_type=code&" + - "client_id=%s&redirect_uri=%s"; - - private static final String TOKEN_URL = "https://hh.ru/oauth/token"; - protected HHApi() { } @@ -29,28 +15,13 @@ public static HHApi instance() { return InstanceHolder.INSTANCE; } - @Override - public Verb getAccessTokenVerb() { - return Verb.POST; - } - @Override public String getAccessTokenEndpoint() { - return TOKEN_URL; - } - - @Override - public String getAuthorizationUrl(OAuthConfig config) { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } - - @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + return "https://hh.ru/oauth/token"; } @Override - public OAuth20Service createService(OAuthConfig config) { - return new HHOAuthServiceImpl(this, config); + protected String getAuthorizationBaseUrl() { + return "https://hh.ru/oauth/authorize"; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/ImgurApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/ImgurApi.java index bcb95cf17..3b14473d1 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/ImgurApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/ImgurApi.java @@ -2,18 +2,14 @@ import com.github.scribejava.apis.service.ImgurOAuthServiceImpl; import com.github.scribejava.core.builder.api.DefaultApi20; -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.Verb; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.ParameterList; import com.github.scribejava.core.oauth.OAuth20Service; +import java.util.Map; public class ImgurApi extends DefaultApi20 { - private static final String AUTHORIZATION_URL = - "https://api.imgur.com/oauth2/authorize?client_id=%s&response_type=%s"; - protected ImgurApi() { } @@ -26,23 +22,37 @@ public static ImgurApi instance() { } @Override - public Verb getAccessTokenVerb() { - return Verb.POST; + public String getAccessTokenEndpoint() { + return "https://api.imgur.com/oauth2/token"; } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); - } + public String getAuthorizationUrl(OAuthConfig config, Map additionalParams) { + final ParameterList parameters = new ParameterList(additionalParams); + parameters.add(OAuthConstants.RESPONSE_TYPE, isOob(config) ? "pin" : "code"); + parameters.add(OAuthConstants.CLIENT_ID, config.getApiKey()); - @Override - public String getAccessTokenEndpoint() { - return "https://api.imgur.com/oauth2/token"; + 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("https://api.imgur.com/oauth2/authorize"); } @Override - public String getAuthorizationUrl(OAuthConfig config) { - return String.format(AUTHORIZATION_URL, config.getApiKey(), isOob(config) ? "pin" : "code"); + protected String getAuthorizationBaseUrl() { + throw new UnsupportedOperationException("use getAuthorizationUrl instead"); } @Override diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/KaixinApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/KaixinApi.java deleted file mode 100644 index e5698bdb6..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/KaixinApi.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.model.Verb; - -public class KaixinApi extends DefaultApi10a { - - private static final String REQUEST_TOKEN_URL = "http://api.kaixin001.com/oauth/request_token"; - private static final String ACCESS_TOKEN_URL = "http://api.kaixin001.com/oauth/access_token"; - private static final String AUTHORIZE_URL = "http://api.kaixin001.com/oauth/authorize?oauth_token=%s"; - - protected KaixinApi() { - } - - private static class InstanceHolder { - private static final KaixinApi INSTANCE = new KaixinApi(); - } - - public static KaixinApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getRequestTokenEndpoint() { - return REQUEST_TOKEN_URL; - } - - @Override - public String getAccessTokenEndpoint() { - return ACCESS_TOKEN_URL; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZE_URL, requestToken.getToken()); - } - - @Override - public Verb getRequestTokenVerb() { - return Verb.GET; - } - - @Override - public Verb getAccessTokenVerb() { - return Verb.GET; - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/KaixinApi20.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/KaixinApi20.java index 1d6658f21..927813535 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/KaixinApi20.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/KaixinApi20.java @@ -1,22 +1,14 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.utils.OAuthEncoder; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; +import com.github.scribejava.core.model.Verb; /** * Kaixin(http://www.kaixin001.com/) open platform api based on OAuth 2.0. */ public class KaixinApi20 extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "http://api.kaixin001.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code"; - private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; - protected KaixinApi20() { } @@ -29,23 +21,22 @@ public static KaixinApi20 instance() { } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public Verb getAccessTokenVerb() { + return Verb.GET; } @Override public String getAccessTokenEndpoint() { - return "https://api.kaixin001.com/oauth2/access_token?grant_type=" + OAuthConstants.AUTHORIZATION_CODE; + return "https://api.kaixin001.com/oauth2/access_token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "http://api.kaixin001.com/oauth2/authorize"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - // Append scope if present - if (config.hasScope()) { - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/LinkedInApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/LinkedInApi.java index 2d876ec5f..f30b44d17 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/LinkedInApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/LinkedInApi.java @@ -10,20 +10,16 @@ public class LinkedInApi extends DefaultApi10a { private final String scopesAsString; - public LinkedInApi() { + protected LinkedInApi() { scopesAsString = null; } - public LinkedInApi(String... scopes) { - if (scopes == null || scopes.length == 0) { - scopesAsString = null; - } else { - final StringBuilder builder = new StringBuilder(); - for (String scope : scopes) { - builder.append('+').append(scope); - } - scopesAsString = "?scope=" + builder.substring(1); + protected LinkedInApi(String... scopes) { + final StringBuilder builder = new StringBuilder(); + for (String scope : scopes) { + builder.append('+').append(scope); } + scopesAsString = "?scope=" + builder.substring(1); } private static class InstanceHolder { @@ -35,6 +31,10 @@ public static LinkedInApi instance() { return InstanceHolder.INSTANCE; } + public static LinkedInApi instance(String... scopes) { + return scopes == null || scopes.length == 0 ? instance() : new LinkedInApi(scopes); + } + @Override public String getAccessTokenEndpoint() { return "https://api.linkedin.com/uas/oauth/accessToken"; diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/LinkedInApi20.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/LinkedInApi20.java index 7f829dd40..0d22d705c 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/LinkedInApi20.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/LinkedInApi20.java @@ -1,25 +1,9 @@ package com.github.scribejava.apis; -import com.github.scribejava.apis.service.LinkedIn20ServiceImpl; import com.github.scribejava.core.builder.api.DefaultApi20; -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.Verb; -import com.github.scribejava.core.oauth.OAuth20Service; -import com.github.scribejava.core.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; public class LinkedInApi20 extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=%s&redirect_uri=%s&" - + OAuthConstants.STATE + "=%s"; - - private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; - protected LinkedInApi20() { } @@ -31,37 +15,13 @@ public static LinkedInApi20 instance() { return InstanceHolder.INSTANCE; } - @Override - public Verb getAccessTokenVerb() { - return Verb.GET; - } - @Override public String getAccessTokenEndpoint() { - return "https://www.linkedin.com/uas/oauth2/accessToken"; - } - - @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. LinkedIn does not support OOB"); - - if (config.hasScope()) { - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - config.getState(), OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - config.getState()); - } - } - - @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + return "https://www.linkedin.com/oauth/v2/accessToken"; } @Override - public OAuth20Service createService(OAuthConfig config) { - return new LinkedIn20ServiceImpl(this, config); + protected String getAuthorizationBaseUrl() { + return "https://www.linkedin.com/oauth/v2/authorization"; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/LiveApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/LiveApi.java index a512318f5..ffaf3bcf6 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/LiveApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/LiveApi.java @@ -1,20 +1,11 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; +import com.github.scribejava.core.model.Verb; public class LiveApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://oauth.live.com/authorize?client_id=%s&redirect_uri=%s&response_type=code"; - private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; - protected LiveApi() { } @@ -26,27 +17,23 @@ public static LiveApi instance() { return InstanceHolder.INSTANCE; } + @Override + public Verb getAccessTokenVerb() { + return Verb.GET; + } + @Override public String getAccessTokenEndpoint() { - return "https://login.live.com/oauth20_token.srf?grant_type=" + OAuthConstants.AUTHORIZATION_CODE; + return "https://login.live.com/oauth20_token.srf"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. Live does not support OOB"); - - // Append scope if present - if (config.hasScope()) { - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } + protected String getAuthorizationBaseUrl() { + return "https://oauth.live.com/authorize"; } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/LoveFilmApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/LoveFilmApi.java deleted file mode 100644 index 3c43ac309..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/LoveFilmApi.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class LoveFilmApi extends DefaultApi10a { - - private static final String REQUEST_TOKEN_URL = "http://openapi.lovefilm.com/oauth/request_token"; - private static final String ACCESS_TOKEN_URL = "http://openapi.lovefilm.com/oauth/access_token"; - private static final String AUTHORIZE_URL = "https://www.lovefilm.com/activate?oauth_token=%s"; - - protected LoveFilmApi() { - } - - private static class InstanceHolder { - private static final LoveFilmApi INSTANCE = new LoveFilmApi(); - } - - public static LoveFilmApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getRequestTokenEndpoint() { - return REQUEST_TOKEN_URL; - } - - @Override - public String getAccessTokenEndpoint() { - return ACCESS_TOKEN_URL; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZE_URL, requestToken.getToken()); - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/MailruApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/MailruApi.java index 3f84704b6..a67e434c5 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/MailruApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/MailruApi.java @@ -1,22 +1,12 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; import com.github.scribejava.apis.service.MailruOAuthServiceImpl; -import com.github.scribejava.core.extractors.TokenExtractor; -import com.github.scribejava.core.model.OAuth2AccessToken; import com.github.scribejava.core.oauth.OAuth20Service; public class MailruApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://connect.mail.ru/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code"; - private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; - protected MailruApi() { } @@ -28,35 +18,18 @@ public static MailruApi instance() { return InstanceHolder.INSTANCE; } - @Override - public Verb getAccessTokenVerb() { - return Verb.POST; - } - @Override public String getAccessTokenEndpoint() { return "https://connect.mail.ru/oauth/token"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Valid url is required for a callback. Mail.ru does not support OOB"); - if (config.hasScope()) { // Appending scope if present - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } + protected String getAuthorizationBaseUrl() { + return "https://connect.mail.ru/oauth/authorize"; } @Override public OAuth20Service createService(OAuthConfig config) { return new MailruOAuthServiceImpl(this, config); } - - @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); - } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/MendeleyApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/MendeleyApi.java deleted file mode 100644 index 9fab6e2ff..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/MendeleyApi.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.model.Verb; - -/** - * @see http://apidocs.mendeley.com/home/authentication - */ -public class MendeleyApi extends DefaultApi10a { - - private static final String AUTHORIZATION_URL = "http://api.mendeley.com/oauth/authorize?oauth_token=%s"; - - protected MendeleyApi() { - } - - private static class InstanceHolder { - private static final MendeleyApi INSTANCE = new MendeleyApi(); - } - - public static MendeleyApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getRequestTokenEndpoint() { - return "http://api.mendeley.com/oauth/request_token/"; - } - - @Override - public String getAccessTokenEndpoint() { - return "http://api.mendeley.com/oauth/access_token/"; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZATION_URL, requestToken.getToken()); - } - - @Override - public Verb getAccessTokenVerb() { - return Verb.GET; - } - - @Override - public Verb getRequestTokenVerb() { - return Verb.GET; - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/MisfitApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/MisfitApi.java new file mode 100644 index 000000000..c34d2cc15 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/MisfitApi.java @@ -0,0 +1,34 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; + +public class MisfitApi extends DefaultApi20 { + + protected MisfitApi() { + } + + private static class InstanceHolder { + + private static final MisfitApi INSTANCE = new MisfitApi(); + } + + public static MisfitApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://api.misfitwearables.com/auth/tokens/exchange"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://api.misfitwearables.com/auth/dialog/authorize"; + } + + @Override + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/MisoApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/MisoApi.java deleted file mode 100644 index 4f0bb3bea..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/MisoApi.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class MisoApi extends DefaultApi10a { - - private static final String AUTHORIZE_URL = "http://gomiso.com/oauth/authorize?oauth_token=%s"; - private static final String REQUEST_TOKEN_RESOURCE = "http://gomiso.com/oauth/request_token"; - private static final String ACCESS_TOKEN_RESOURCE = "http://gomiso.com/oauth/access_token"; - - protected MisoApi() { - } - - private static class InstanceHolder { - private static final MisoApi INSTANCE = new MisoApi(); - } - - public static MisoApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAccessTokenEndpoint() { - return ACCESS_TOKEN_RESOURCE; - } - - @Override - public String getRequestTokenEndpoint() { - return REQUEST_TOKEN_RESOURCE; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZE_URL, requestToken.getToken()); - } - -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/NaverApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/NaverApi.java new file mode 100644 index 000000000..a3028ae11 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/NaverApi.java @@ -0,0 +1,35 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; + +public class NaverApi extends DefaultApi20 { + protected NaverApi() { + } + + private static class InstanceHolder { + private static final NaverApi INSTANCE = new NaverApi(); + + private InstanceHolder() { + } + } + + public static NaverApi instance() { + return NaverApi.InstanceHolder.INSTANCE; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://nid.naver.com/oauth2.0/authorize"; + } + + @Override + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/NetProspexApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/NetProspexApi.java deleted file mode 100644 index aa08abc4a..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/NetProspexApi.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class NetProspexApi extends DefaultApi10a { - - private static final String REQUEST_TOKEN_URL = "https://api.netprospex.com/1.0/oauth/request-token"; - private static final String ACCESS_TOKEN_URL = "https://api.netprospex.com/1.0/oauth/access-token"; - private static final String AUTHORIZE_URL = "https://api.netprospex.com/1.0/oauth/authorize?oauth_token=%s"; - - protected NetProspexApi() { - } - - private static class InstanceHolder { - private static final NetProspexApi INSTANCE = new NetProspexApi(); - } - - public static NetProspexApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getRequestTokenEndpoint() { - return REQUEST_TOKEN_URL; - } - - @Override - public String getAccessTokenEndpoint() { - return ACCESS_TOKEN_URL; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZE_URL, requestToken.getToken()); - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/NeteaseWeibooApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/NeteaseWeibooApi.java index 317d1e74e..91edb38ca 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/NeteaseWeibooApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/NeteaseWeibooApi.java @@ -32,14 +32,15 @@ public String getAccessTokenEndpoint() { return ACCESS_TOKEN_URL; } - @Override /** * this method will ignore your callback if you're creating a desktop client please choose this url else your can * call getAuthenticateUrl * * via * http://open.t.163.com/wiki/index.php?title=%E8%AF%B7%E6%B1%82%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83Token(oauth/authorize) + * @return url to redirect user to (to get code) */ + @Override public String getAuthorizationUrl(OAuth1RequestToken requestToken) { return String.format(AUTHORIZE_URL, requestToken.getToken()); } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/OdnoklassnikiApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/OdnoklassnikiApi.java index 1842e9faa..f8e1a40ef 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/OdnoklassnikiApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/OdnoklassnikiApi.java @@ -2,21 +2,12 @@ import com.github.scribejava.apis.service.OdnoklassnikiServiceImpl; import com.github.scribejava.core.builder.api.DefaultApi20; -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.builder.api.OAuth2SignatureType; import com.github.scribejava.core.model.OAuthConfig; -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 OdnoklassnikiApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "http://www.odnoklassniki.ru/oauth/authorize?client_id=%s&response_type=code&redirect_uri=%s"; - private static final String SCOPED_AUTHORIZE_URL = String.format("%s&scope=%%s", AUTHORIZE_URL); - protected OdnoklassnikiApi() { } @@ -30,24 +21,12 @@ public static OdnoklassnikiApi instance() { @Override public String getAccessTokenEndpoint() { - return "http://api.odnoklassniki.ru/oauth/token.do"; - } - - @Override - public Verb getAccessTokenVerb() { - return Verb.POST; + return "https://api.ok.ru/oauth/token.do"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Valid url is required for a callback. Odnoklassniki does not support OOB"); - if (config.hasScope()) { - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } + protected String getAuthorizationBaseUrl() { + return "https://connect.ok.ru/oauth/authorize"; } @Override @@ -56,7 +35,7 @@ public OAuth20Service createService(OAuthConfig config) { } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/PinterestApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/PinterestApi.java index 6880cd938..d93404b5e 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/PinterestApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/PinterestApi.java @@ -1,21 +1,10 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.Verb; -import com.github.scribejava.core.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; public class PinterestApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://api.pinterest.com/oauth?response_type=code&client_id=%s&redirect_uri=%s"; - private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; - protected PinterestApi() { } @@ -29,30 +18,16 @@ public static PinterestApi instance() { @Override public String getAccessTokenEndpoint() { - return "https://api.pinterest.com/v1/oauth/token?grant_type=" + OAuthConstants.AUTHORIZATION_CODE; - } - - @Override - public Verb getAccessTokenVerb() { - return Verb.POST; + return "https://api.pinterest.com/v1/oauth/token"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. Pinterest does not support OOB"); - - // Append scope if present - if (config.hasScope()) { - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } + protected String getAuthorizationBaseUrl() { + return "https://api.pinterest.com/oauth"; } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/PlurkApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/PlurkApi.java deleted file mode 100644 index f2b9c5ed2..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/PlurkApi.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class PlurkApi extends DefaultApi10a { - - private static final String REQUEST_TOKEN_URL = "http://www.plurk.com/OAuth/request_token"; - private static final String AUTHORIZATION_URL = "http://www.plurk.com/OAuth/authorize?oauth_token=%s"; - private static final String ACCESS_TOKEN_URL = "http://www.plurk.com/OAuth/access_token"; - - protected PlurkApi() { - } - - private static class InstanceHolder { - private static final PlurkApi INSTANCE = new PlurkApi(); - } - - public static PlurkApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getRequestTokenEndpoint() { - return REQUEST_TOKEN_URL; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZATION_URL, requestToken.getToken()); - } - - @Override - public String getAccessTokenEndpoint() { - return ACCESS_TOKEN_URL; - } - - public static class Mobile extends PlurkApi { - - private static final String AUTHORIZATION_URL = "http://www.plurk.com/m/authorize?oauth_token=%s"; - - private Mobile() { - } - - private static class InstanceHolder { - private static final Mobile INSTANCE = new Mobile(); - } - - public static Mobile instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZATION_URL, requestToken.getToken()); - } - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/QWeiboApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/QWeiboApi.java deleted file mode 100644 index ed4bfdb6b..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/QWeiboApi.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class QWeiboApi extends DefaultApi10a { - - private static final String REQUEST_TOKEN_URL = "https://open.t.qq.com/cgi-bin/request_token"; - private static final String ACCESS_TOKEN_URL = "https://open.t.qq.com/cgi-bin/access_token"; - private static final String AUTHORIZE_URL = "https://open.t.qq.com/cgi-bin/authorize?oauth_token=%s"; - - protected QWeiboApi() { - } - - private static class InstanceHolder { - private static final QWeiboApi INSTANCE = new QWeiboApi(); - } - - public static QWeiboApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getRequestTokenEndpoint() { - return REQUEST_TOKEN_URL; - } - - @Override - public String getAccessTokenEndpoint() { - return ACCESS_TOKEN_URL; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZE_URL, requestToken.getToken()); - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/RenrenApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/RenrenApi.java index 4fd12b36b..cc475440e 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/RenrenApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/RenrenApi.java @@ -1,22 +1,14 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.utils.OAuthEncoder; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; +import com.github.scribejava.core.model.Verb; /** * Renren(http://www.renren.com/) OAuth 2.0 based api. */ public class RenrenApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://graph.renren.com/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code"; - private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; - protected RenrenApi() { } @@ -29,23 +21,22 @@ public static RenrenApi instance() { } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public Verb getAccessTokenVerb() { + return Verb.GET; } @Override public String getAccessTokenEndpoint() { - return "https://graph.renren.com/oauth/token?grant_type=" + OAuthConstants.AUTHORIZATION_CODE; + return "https://graph.renren.com/oauth/token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://graph.renren.com/oauth/authorize"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - // Append scope if present - if (config.hasScope()) { - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/SalesforceApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/SalesforceApi.java new file mode 100644 index 000000000..95e5e2816 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/SalesforceApi.java @@ -0,0 +1,132 @@ +package com.github.scribejava.apis; + +import javax.net.ssl.SSLContext; + +import com.github.scribejava.apis.salesforce.SalesforceJsonTokenExtractor; +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.extractors.TokenExtractor; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.Verb; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import javax.net.ssl.SSLSocket; + +/** + * This class is an implementation of the Salesforce OAuth2 API. + * The default implementation connects to the Salesforce + * production environment. + * If you want to connect to a Sandbox environment you've to use {@link #sandbox()} method to + * get sandbox instance of this API + */ +public class SalesforceApi extends DefaultApi20 { + + private static final String PRODUCTION_HOST = "login.salesforce.com"; + private static final String SANDBOX_HOST = "test.salesforce.com"; + private static final String PROTOCOL = "https://"; + private static final String ACCESS_PATH = "/services/oauth2/token"; + private static final String AUTHORIZE_PATH = "/services/oauth2/authorize"; + + private final String accessTokenUrl; + private final String authorizationBaseUrl; + + /** + * @param hostName The hostname to be used, which is either {@link #PRODUCTION_HOST} or {@link #SANDBOX_HOST}. + */ + protected SalesforceApi(String hostName) { + accessTokenUrl = PROTOCOL + hostName + ACCESS_PATH; + authorizationBaseUrl = PROTOCOL + hostName + AUTHORIZE_PATH; + try { + final SSLSocket socket = (SSLSocket) SSLContext.getDefault().getSocketFactory().createSocket(); + if (!isTLSv11orUpperEnabled(socket)) { + throw new IllegalStateException("Salesforce API required to use TLSv1.1 or upper. " + + "Enabled it by invoking method initTLSv11orUpper or somehow else"); + } + } catch (NoSuchAlgorithmException | IOException ex) { + throw new IllegalStateException("Salesforce API required to use TLSv1.1 or upper. " + + "Enabled it by invoking method initTLSv11orUpper or somehow else"); + } + } + + private static class InstanceHolder { + private static final SalesforceApi INSTANCE = new SalesforceApi(PRODUCTION_HOST); + } + + public static SalesforceApi instance() { + return InstanceHolder.INSTANCE; + } + + public static SalesforceApi sandbox() { + return new SalesforceApi(SANDBOX_HOST); + } + + @Override + public Verb getAccessTokenVerb() { + return Verb.POST; + } + + @Override + public String getAccessTokenEndpoint() { + return accessTokenUrl; + } + + @Override + protected String getAuthorizationBaseUrl() { + return authorizationBaseUrl; + } + + @Override + public TokenExtractor getAccessTokenExtractor() { + return SalesforceJsonTokenExtractor.instance(); + } + + private static boolean isTLSv11orUpperEnabled(final SSLSocket socket) { + for (String protocol : socket.getEnabledProtocols()) { + if ("TLSv1.2".equals(protocol) || "TLSv1.1".equals(protocol)) { + return true; + } + } + return false; + } + + /** + * Salesforce API requires to use TLSv1.1 or upper. + *

+ * Java 8 have TLS 1.2 enabled by default. java 7 - no, you should invoke this method or turn TLS>=1.1 somehow + * else

+ * + * @throws java.security.NoSuchAlgorithmException in case your jvm doesn't support TLSv1.1 and TLSv1.2 + * @throws java.security.KeyManagementException unexpected Exception from + * {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom)} + * @throws java.io.IOException unexpected Exception from {@link javax.net.ssl.SSLSocketFactory#createSocket()} + */ + public static void initTLSv11orUpper() throws NoSuchAlgorithmException, KeyManagementException, IOException { + final SSLSocket socket = (SSLSocket) SSLContext.getDefault().getSocketFactory().createSocket(); + if (isTLSv11orUpperEnabled(socket)) { + return; + } + boolean supportTLSv11 = false; + boolean supportTLSv12 = false; + for (String protocol : socket.getSupportedProtocols()) { + if ("TLSv1.2".equals(protocol)) { + supportTLSv12 = true; + break; + } + if ("TLSv1.1".equals(protocol)) { + supportTLSv11 = true; + } + } + + final SSLContext context; + if (supportTLSv12) { + context = SSLContext.getInstance("TLSv1.2"); + } else if (supportTLSv11) { + context = SSLContext.getInstance("TLSv1.1"); + } else { + throw new NoSuchAlgorithmException("for Salesforce API to work you need jvm with TLS 1.1 or 1.2 support"); + } + + context.init(null, null, null); + SSLContext.setDefault(context); + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/SapoApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/SapoApi.java deleted file mode 100644 index 524ddfcf7..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/SapoApi.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.model.Verb; - -public class SapoApi extends DefaultApi10a { - - private static final String AUTHORIZE_URL = "https://id.sapo.pt/oauth/authorize?oauth_token=%s"; - private static final String ACCESS_URL = "https://id.sapo.pt/oauth/access_token"; - private static final String REQUEST_URL = "https://id.sapo.pt/oauth/request_token"; - - protected SapoApi() { - } - - private static class InstanceHolder { - private static final SapoApi INSTANCE = new SapoApi(); - } - - public static SapoApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAccessTokenEndpoint() { - return ACCESS_URL; - } - - @Override - public String getRequestTokenEndpoint() { - return REQUEST_URL; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZE_URL, requestToken.getToken()); - } - - @Override - public Verb getRequestTokenVerb() { - return Verb.GET; - } - - @Override - public Verb getAccessTokenVerb() { - return Verb.GET; - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/SimpleGeoApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/SimpleGeoApi.java deleted file mode 100644 index c8264b19b..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/SimpleGeoApi.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class SimpleGeoApi extends DefaultApi10a { - - private static final String ENDPOINT = "these are not used since SimpleGeo uses 2 legged OAuth"; - - protected SimpleGeoApi() { - } - - private static class InstanceHolder { - private static final SimpleGeoApi INSTANCE = new SimpleGeoApi(); - } - - public static SimpleGeoApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getRequestTokenEndpoint() { - return ENDPOINT; - } - - @Override - public String getAccessTokenEndpoint() { - return ENDPOINT; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return ENDPOINT; - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/SinaWeiboApi20.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/SinaWeiboApi20.java index a98493382..edd316f87 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/SinaWeiboApi20.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/SinaWeiboApi20.java @@ -1,23 +1,13 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.Verb; -import com.github.scribejava.core.utils.OAuthEncoder; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; /** * SinaWeibo OAuth 2.0 api. */ public class SinaWeiboApi20 extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://api.weibo.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code"; - private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; - protected SinaWeiboApi20() { } @@ -30,28 +20,17 @@ public static SinaWeiboApi20 instance() { } @Override - public Verb getAccessTokenVerb() { - return Verb.POST; - } - - @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public String getAccessTokenEndpoint() { + return "https://api.weibo.com/oauth2/access_token"; } @Override - public String getAccessTokenEndpoint() { - return "https://api.weibo.com/oauth2/access_token?grant_type=" + OAuthConstants.AUTHORIZATION_CODE; + protected String getAuthorizationBaseUrl() { + return "https://api.weibo.com/oauth2/authorize"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - // Append scope if present - if (config.hasScope()) { - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/StackExchangeApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/StackExchangeApi.java index 77e257839..554c97b33 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/StackExchangeApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/StackExchangeApi.java @@ -1,11 +1,10 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; +import com.github.scribejava.core.extractors.OAuth2AccessTokenExtractor; +import com.github.scribejava.core.extractors.TokenExtractor; +import com.github.scribejava.core.model.OAuth2AccessToken; /** * Stack Exchange authentication via OAuth 2.0 (stackoverflow.com, @@ -13,8 +12,6 @@ */ public class StackExchangeApi extends DefaultApi20 { - private static final String AUTHORIZE_URL = "https://stackexchange.com/oauth?client_id=%s&redirect_uri=%s"; - protected StackExchangeApi() { } @@ -27,29 +24,22 @@ public static StackExchangeApi instance() { } @Override - public Verb getAccessTokenVerb() { - return Verb.POST; + public String getAccessTokenEndpoint() { + return "https://stackexchange.com/oauth/access_token"; } @Override - public String getAccessTokenEndpoint() { - return "https://stackexchange.com/oauth/access_token"; + protected String getAuthorizationBaseUrl() { + return "https://stackexchange.com/oauth"; + } + + @Override + public TokenExtractor getAccessTokenExtractor() { + return OAuth2AccessTokenExtractor.instance(); } @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. StackExchange 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)); - } - return sb.toString(); + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/TheThingsNetworkV1StagingApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/TheThingsNetworkV1StagingApi.java new file mode 100644 index 000000000..844d75758 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/TheThingsNetworkV1StagingApi.java @@ -0,0 +1,27 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.core.builder.api.DefaultApi20; + +public class TheThingsNetworkV1StagingApi extends DefaultApi20 { + + protected TheThingsNetworkV1StagingApi() { + } + + private static class InstanceHolder { + private static final TheThingsNetworkV1StagingApi INSTANCE = new TheThingsNetworkV1StagingApi(); + } + + public static TheThingsNetworkV1StagingApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://account.thethingsnetwork.org/users/token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://account.thethingsnetwork.org/users/authorize"; + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/TheThingsNetworkV2PreviewApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/TheThingsNetworkV2PreviewApi.java new file mode 100644 index 000000000..1ac5437a0 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/TheThingsNetworkV2PreviewApi.java @@ -0,0 +1,27 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.core.builder.api.DefaultApi20; + +public class TheThingsNetworkV2PreviewApi extends DefaultApi20 { + + protected TheThingsNetworkV2PreviewApi() { + } + + private static class InstanceHolder { + private static final TheThingsNetworkV2PreviewApi INSTANCE = new TheThingsNetworkV2PreviewApi(); + } + + public static TheThingsNetworkV2PreviewApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public String getAccessTokenEndpoint() { + return "https://preview.account.thethingsnetwork.org/users/token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://preview.account.thethingsnetwork.org/users/authorize"; + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/TutByApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/TutByApi.java index fb1e10820..6928ba70a 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/TutByApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/TutByApi.java @@ -1,21 +1,12 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; import com.github.scribejava.apis.service.TutByOAuthServiceImpl; -import com.github.scribejava.core.extractors.TokenExtractor; -import com.github.scribejava.core.model.OAuth2AccessToken; import com.github.scribejava.core.oauth.OAuth20Service; public class TutByApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "http://profile.tut.by/auth?client_id=%s&response_type=code&redirect_uri=%s"; - protected TutByApi() { } @@ -33,24 +24,12 @@ public String getAccessTokenEndpoint() { } @Override - public Verb getAccessTokenVerb() { - return Verb.POST; - } - - @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Valid url is required for a callback. Tut.by does not support OOB"); - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); + protected String getAuthorizationBaseUrl() { + return "http://profile.tut.by/auth"; } @Override public OAuth20Service createService(OAuthConfig config) { return new TutByOAuthServiceImpl(this, config); } - - @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); - } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/UbuntuOneApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/UbuntuOneApi.java deleted file mode 100644 index 867b7556a..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/UbuntuOneApi.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.services.PlaintextSignatureService; -import com.github.scribejava.core.services.SignatureService; - -public class UbuntuOneApi extends DefaultApi10a { - - private static final String AUTHORIZATION_URL = "https://one.ubuntu.com/oauth/authorize/?oauth_token=%s"; - - protected UbuntuOneApi() { - } - - private static class InstanceHolder { - private static final UbuntuOneApi INSTANCE = new UbuntuOneApi(); - } - - public static UbuntuOneApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAccessTokenEndpoint() { - return "https://one.ubuntu.com/oauth/access/"; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZATION_URL, requestToken.getToken()); - } - - @Override - public String getRequestTokenEndpoint() { - return "https://one.ubuntu.com/oauth/request/"; - } - - @Override - public SignatureService getSignatureService() { - return new PlaintextSignatureService(); - } - -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/ViadeoApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/ViadeoApi.java index c4f718d81..30c0ffcfe 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/ViadeoApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/ViadeoApi.java @@ -1,20 +1,11 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; +import com.github.scribejava.core.model.Verb; public class ViadeoApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://secure.viadeo.com/oauth-provider/authorize2?client_id=%s&redirect_uri=%s&response_type=code"; - private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s"; - protected ViadeoApi() { } @@ -27,26 +18,22 @@ public static ViadeoApi instance() { } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public Verb getAccessTokenVerb() { + return Verb.GET; } @Override public String getAccessTokenEndpoint() { - return "https://secure.viadeo.com/oauth-provider/access_token2?grant_type=" + OAuthConstants.AUTHORIZATION_CODE; + return "https://secure.viadeo.com/oauth-provider/access_token2"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "https://secure.viadeo.com/oauth-provider/authorize2"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Must provide a valid url as callback. Viadeo does not support OOB"); - - // Append scope if present - if (config.hasScope()) { - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/VimeoApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/VimeoApi.java deleted file mode 100644 index 63ecb844d..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/VimeoApi.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; - -public class VimeoApi extends DefaultApi10a { - - private static final String AUTHORIZATION_URL = "http://vimeo.com/oauth/authorize?oauth_token=%s"; - - protected VimeoApi() { - } - - private static class InstanceHolder { - private static final VimeoApi INSTANCE = new VimeoApi(); - } - - public static VimeoApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getAccessTokenEndpoint() { - return "http://vimeo.com/oauth/access_token"; - } - - @Override - public String getRequestTokenEndpoint() { - return "http://vimeo.com/oauth/request_token"; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZATION_URL, requestToken.getToken()); - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/VkontakteApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/VkontakteApi.java index b0b4e345c..285cb2cde 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/VkontakteApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/VkontakteApi.java @@ -1,19 +1,11 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; +import com.github.scribejava.core.model.Verb; public class VkontakteApi extends DefaultApi20 { - private static final String AUTHORIZE_URL - = "https://oauth.vk.com/authorize?client_id=%s&redirect_uri=%s&response_type=code"; - private static final String SCOPED_AUTHORIZE_URL = String.format("%s&scope=%%s", AUTHORIZE_URL); - protected VkontakteApi() { } @@ -25,25 +17,23 @@ public static VkontakteApi instance() { return InstanceHolder.INSTANCE; } + @Override + public Verb getAccessTokenVerb() { + return Verb.GET; + } + @Override public String getAccessTokenEndpoint() { return "https://oauth.vk.com/access_token"; } @Override - public String getAuthorizationUrl(OAuthConfig config) { - Preconditions.checkValidUrl(config.getCallback(), - "Valid url is required for a callback. Vkontakte does not support OOB"); - if (config.hasScope()) { // Appending scope if present - return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback()), - OAuthEncoder.encode(config.getScope())); - } else { - return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); - } + protected String getAuthorizationBaseUrl() { + return "https://oauth.vk.com/authorize"; } @Override - public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenJsonExtractor.instance(); + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/YammerApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/YammerApi.java deleted file mode 100644 index 269e61395..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/YammerApi.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.github.scribejava.apis; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.services.PlaintextSignatureService; -import com.github.scribejava.core.services.SignatureService; - -public class YammerApi extends DefaultApi10a { - - private static final String AUTHORIZATION_URL = "https://www.yammer.com/oauth/authorize?oauth_token=%s"; - - protected YammerApi() { - } - - private static class InstanceHolder { - private static final YammerApi INSTANCE = new YammerApi(); - } - - public static YammerApi instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public String getRequestTokenEndpoint() { - return "https://www.yammer.com/oauth/request_token"; - } - - @Override - public String getAccessTokenEndpoint() { - return "https://www.yammer.com/oauth/access_token"; - } - - @Override - public String getAuthorizationUrl(OAuth1RequestToken requestToken) { - return String.format(AUTHORIZATION_URL, requestToken.getToken()); - } - - @Override - public SignatureService getSignatureService() { - return new PlaintextSignatureService(); - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/constantcontact/ConstantContactTokenExtractor.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/constantcontact/ConstantContactTokenExtractor.java deleted file mode 100644 index f385eba1d..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/constantcontact/ConstantContactTokenExtractor.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.github.scribejava.apis.constantcontact; - -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.extractors.TokenExtractor; -import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.utils.OAuthEncoder; -import com.github.scribejava.core.utils.Preconditions; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class ConstantContactTokenExtractor implements TokenExtractor { - - private static final String REGEXP = "\"access_token\"\\s*:\\s*\"([^&\"]+)\""; - - protected ConstantContactTokenExtractor() { - } - - private static class InstanceHolder { - - private static final ConstantContactTokenExtractor INSTANCE = new ConstantContactTokenExtractor(); - } - - public static ConstantContactTokenExtractor instance() { - return InstanceHolder.INSTANCE; - } - - @Override - public OAuth2AccessToken extract(String response) { - Preconditions.checkEmptyString(response, - "Response body is incorrect. Can't extract a token from an empty string"); - - final Matcher matcher = Pattern.compile(REGEXP).matcher(response); - if (matcher.find()) { - final String token = OAuthEncoder.decode(matcher.group(1)); - return new OAuth2AccessToken(token, response); - } else { - throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" - + response + "'", null); - } - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponse.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponse.java new file mode 100644 index 000000000..30c049a3f --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponse.java @@ -0,0 +1,95 @@ +package com.github.scribejava.apis.facebook; + +import com.github.scribejava.core.exceptions.OAuthException; +import java.util.Objects; + +/** + * non standard Facebook replace for {@link com.github.scribejava.core.model.OAuth2AccessTokenErrorResponse} + * + * examples:
+ * + * '{"error":{"message":"This authorization code has been + * used.","type":"OAuthException","code":100,"fbtrace_id":"DtxvtGRaxbB"}}'
+ * + * '{"error":{"message":"Error validating application. Invalid application + * ID.","type":"OAuthException","code":101,"fbtrace_id":"CvDR+X4WWIx"}}' + */ +public class FacebookAccessTokenErrorResponse extends OAuthException { + + private static final long serialVersionUID = -1277129766099856895L; + + private final String type; + private final String code; + private final String fbtraceId; + private final String rawResponse; + + public FacebookAccessTokenErrorResponse(String message, String type, String code, String fbtraceId, + String rawResponse) { + super(message); + this.type = type; + this.code = code; + this.fbtraceId = fbtraceId; + this.rawResponse = rawResponse; + } + + public String getType() { + return type; + } + + public String getCode() { + return code; + } + + public String getFbtraceId() { + return fbtraceId; + } + + public String getRawResponse() { + return rawResponse; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 83 * hash + Objects.hashCode(rawResponse); + hash = 83 * hash + Objects.hashCode(getMessage()); + hash = 83 * hash + Objects.hashCode(type); + hash = 83 * hash + Objects.hashCode(code); + hash = 83 * hash + Objects.hashCode(fbtraceId); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final FacebookAccessTokenErrorResponse other = (FacebookAccessTokenErrorResponse) obj; + if (!Objects.equals(rawResponse, other.getRawResponse())) { + return false; + } + if (!Objects.equals(getMessage(), other.getMessage())) { + return false; + } + if (!Objects.equals(type, other.getType())) { + return false; + } + if (!Objects.equals(code, other.getCode())) { + return false; + } + return Objects.equals(fbtraceId, other.getFbtraceId()); + } + + @Override + public String toString() { + return "FacebookAccessTokenErrorResponse{'type'='" + type + "', 'code'='" + code + + "', 'fbtraceId'='" + fbtraceId + "', 'rawResponse'='" + rawResponse + + "', 'message'='" + getMessage() + "'}"; + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenJsonExtractor.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenJsonExtractor.java new file mode 100644 index 000000000..5f6d71d44 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenJsonExtractor.java @@ -0,0 +1,47 @@ +package com.github.scribejava.apis.facebook; + +import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; +import java.util.regex.Pattern; + +/** + * non standard Facebook Extractor + */ +public class FacebookAccessTokenJsonExtractor extends OAuth2AccessTokenJsonExtractor { + + private static final Pattern MESSAGE_REGEX_PATTERN = Pattern.compile("\"message\"\\s*:\\s*\"([^\"]*?)\""); + private static final Pattern TYPE_REGEX_PATTERN = Pattern.compile("\"type\"\\s*:\\s*\"([^\"]*?)\""); + private static final Pattern CODE_REGEX_PATTERN = Pattern.compile("\"code\"\\s*:\\s*\"?([^\",}]*?)[\",}]"); + private static final Pattern FBTRACE_ID_REGEX_PATTERN = Pattern.compile("\"fbtrace_id\"\\s*:\\s*\"([^\"]*?)\""); + + protected FacebookAccessTokenJsonExtractor() { + } + + private static class InstanceHolder { + + private static final FacebookAccessTokenJsonExtractor INSTANCE = new FacebookAccessTokenJsonExtractor(); + } + + public static FacebookAccessTokenJsonExtractor instance() { + return InstanceHolder.INSTANCE; + } + + /** + * non standard. examples:
+ * + * '{"error":{"message":"This authorization code has been + * used.","type":"OAuthException","code":100,"fbtrace_id":"DtxvtGRaxbB"}}'
+ * + * '{"error":{"message":"Error validating application. Invalid application + * ID.","type":"OAuthException","code":101,"fbtrace_id":"CvDR+X4WWIx"}}' + */ + @Override + protected void generateError(String response) { + extractParameter(response, MESSAGE_REGEX_PATTERN, false); + + throw new FacebookAccessTokenErrorResponse(extractParameter(response, MESSAGE_REGEX_PATTERN, false), + extractParameter(response, TYPE_REGEX_PATTERN, false), + extractParameter(response, CODE_REGEX_PATTERN, false), + extractParameter(response, FBTRACE_ID_REGEX_PATTERN, false), response); + } + +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleJsonTokenExtractor.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleJsonTokenExtractor.java index 13b7cff39..722390ae0 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleJsonTokenExtractor.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleJsonTokenExtractor.java @@ -1,15 +1,14 @@ package com.github.scribejava.apis.google; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; +import java.util.regex.Pattern; /** * additionally parses OpenID id_token */ public class GoogleJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor { - private static final String REGEXP = "\"id_token\"\\s*:\\s*\"(\\S*?)\""; + private static final Pattern ID_TOKEN_REGEX_PATTERN = Pattern.compile("\"id_token\"\\s*:\\s*\"(\\S*?)\""); protected GoogleJsonTokenExtractor() { } @@ -24,15 +23,9 @@ public static GoogleJsonTokenExtractor instance() { } @Override - public GoogleToken extract(String response) { - return new GoogleToken(extractAccessToken(response), extractOpenIdToken(response), response); - } - - private String extractOpenIdToken(String response) { - final Matcher matcher = Pattern.compile(REGEXP).matcher(response); - if (matcher.find()) { - return matcher.group(1); - } - return null; + protected GoogleToken createToken(String accessToken, String tokenType, Integer expiresIn, + String refreshToken, String scope, String response) { + return new GoogleToken(accessToken, tokenType, expiresIn, refreshToken, scope, + extractParameter(response, ID_TOKEN_REGEX_PATTERN, false), response); } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleToken.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleToken.java index 1afe0b084..68ec31f82 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleToken.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleToken.java @@ -5,7 +5,7 @@ public class GoogleToken extends OAuth2AccessToken { - private static final long serialVersionUID = 6150970703986214220L; + private static final long serialVersionUID = 7845679917727899612L; /** * Id_token is part of OpenID Connect specification. It can hold user information that you can directly extract @@ -19,7 +19,12 @@ public class GoogleToken extends OAuth2AccessToken { private final String openIdToken; public GoogleToken(String accessToken, String openIdToken, String rawResponse) { - super(accessToken, rawResponse); + this(accessToken, null, null, null, null, openIdToken, rawResponse); + } + + public GoogleToken(String accessToken, String tokenType, Integer expiresIn, String refreshToken, String scope, + String openIdToken, String rawResponse) { + super(accessToken, tokenType, expiresIn, refreshToken, scope, rawResponse); this.openIdToken = openIdToken; } @@ -29,12 +34,7 @@ public String getOpenIdToken() { @Override public int hashCode() { - int hash = 5; - hash = 37 * hash + Objects.hashCode(getAccessToken()); - hash = 37 * hash + Objects.hashCode(getTokenType()); - hash = 37 * hash + Objects.hashCode(getExpiresIn()); - hash = 37 * hash + Objects.hashCode(getRefreshToken()); - hash = 37 * hash + Objects.hashCode(getScope()); + int hash = super.hashCode(); hash = 37 * hash + Objects.hashCode(openIdToken); return hash; } @@ -50,23 +50,11 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final GoogleToken other = (GoogleToken) obj; - if (!Objects.equals(getAccessToken(), other.getAccessToken())) { - return false; - } - if (!Objects.equals(getTokenType(), other.getTokenType())) { - return false; - } - if (!Objects.equals(getRefreshToken(), other.getRefreshToken())) { + if (!super.equals(obj)) { return false; } - if (!Objects.equals(getScope(), other.getScope())) { - return false; - } - if (!Objects.equals(openIdToken, other.getOpenIdToken())) { - return false; - } - return Objects.equals(getExpiresIn(), other.getExpiresIn()); + + return Objects.equals(openIdToken, ((GoogleToken) obj).getOpenIdToken()); } @Override diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/salesforce/SalesforceJsonTokenExtractor.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/salesforce/SalesforceJsonTokenExtractor.java new file mode 100644 index 000000000..841276724 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/salesforce/SalesforceJsonTokenExtractor.java @@ -0,0 +1,32 @@ +package com.github.scribejava.apis.salesforce; + +import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; +import java.util.regex.Pattern; + +/** + * This extractor parses in addition to the standard Extractor the instance_url + * of the used Salesforce organization. + */ +public class SalesforceJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor { + + private static final Pattern INSTANCE_URL_REGEX_PATTERN = Pattern.compile("\"instance_url\"\\s*:\\s*\"(\\S*?)\""); + + protected SalesforceJsonTokenExtractor() { + } + + private static class InstanceHolder { + + private static final SalesforceJsonTokenExtractor INSTANCE = new SalesforceJsonTokenExtractor(); + } + + public static SalesforceJsonTokenExtractor instance() { + return InstanceHolder.INSTANCE; + } + + @Override + protected SalesforceToken createToken(String accessToken, String tokenType, Integer expiresIn, + String refreshToken, String scope, String response) { + return new SalesforceToken(accessToken, tokenType, expiresIn, refreshToken, scope, + extractParameter(response, INSTANCE_URL_REGEX_PATTERN, true), response); + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/salesforce/SalesforceToken.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/salesforce/SalesforceToken.java new file mode 100644 index 000000000..14a0911cd --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/salesforce/SalesforceToken.java @@ -0,0 +1,65 @@ +package com.github.scribejava.apis.salesforce; + +import java.util.Objects; + +import com.github.scribejava.core.model.OAuth2AccessToken; + +public class SalesforceToken extends OAuth2AccessToken { + + private static final long serialVersionUID = 7496092256264195577L; + + /** + * This token model includes the instance_url to address the needed + * Salesforce organization instance. + */ + private final String instanceUrl; + + public SalesforceToken(String accessToken, String instanceUrl, String rawResponse) { + this(accessToken, null, null, null, null, instanceUrl, rawResponse); + } + + public SalesforceToken(String accessToken, String tokenType, Integer expiresIn, String refreshToken, String scope, + String instanceUrl, String rawResponse) { + super(accessToken, tokenType, expiresIn, refreshToken, scope, rawResponse); + this.instanceUrl = instanceUrl; + } + + public String getInstanceUrl() { + return instanceUrl; + } + + @Override + public int hashCode() { + int hash = super.hashCode(); + hash = 37 * hash + Objects.hashCode(instanceUrl); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + if (!super.equals(obj)) { + return false; + } + return Objects.equals(instanceUrl, ((SalesforceToken) obj).getInstanceUrl()); + } + + @Override + public String toString() { + return "SalesforceToken{" + + "access_token=" + getAccessToken() + + ", token_type=" + getTokenType() + + ", expires_in=" + getExpiresIn() + + ", refresh_token=" + getRefreshToken() + + ", scope=" + getScope() + + ", instance_url=" + instanceUrl + '}'; + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/DoktornaraboteOAuthServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/DoktornaraboteOAuthServiceImpl.java deleted file mode 100644 index 837449436..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/DoktornaraboteOAuthServiceImpl.java +++ /dev/null @@ -1,19 +0,0 @@ -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.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.oauth.OAuth20Service; - -public class DoktornaraboteOAuthServiceImpl extends OAuth20Service { - - public DoktornaraboteOAuthServiceImpl(DefaultApi20 api, OAuthConfig config) { - super(api, config); - } - - @Override - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { - request.addHeader("Authorization", "Bearer " + accessToken.getAccessToken()); - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/GoogleOAuthServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/GoogleOAuthServiceImpl.java deleted file mode 100644 index 300872853..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/GoogleOAuthServiceImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -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.model.Verifier; -import com.github.scribejava.core.oauth.OAuth20Service; - -public class GoogleOAuthServiceImpl extends OAuth20Service { - - public GoogleOAuthServiceImpl(DefaultApi20 api, OAuthConfig config) { - super(api, config); - } - - @Override - protected T createAccessTokenRequest(Verifier verifier, T request) { - super.createAccessTokenRequest(verifier, request); - if (!getConfig().hasGrantType()) { - request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.AUTHORIZATION_CODE); - } - return request; - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/HHOAuthServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/HHOAuthServiceImpl.java deleted file mode 100644 index 8d1799272..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/HHOAuthServiceImpl.java +++ /dev/null @@ -1,19 +0,0 @@ -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.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.oauth.OAuth20Service; - -public class HHOAuthServiceImpl extends OAuth20Service { - - public HHOAuthServiceImpl(DefaultApi20 api, OAuthConfig config) { - super(api, config); - } - - @Override - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { - request.addHeader("Authorization", "Bearer " + accessToken.getAccessToken()); - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/ImgurOAuthServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/ImgurOAuthServiceImpl.java index fcc791ac1..c0f74aab6 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/ImgurOAuthServiceImpl.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/ImgurOAuthServiceImpl.java @@ -2,11 +2,10 @@ import com.github.scribejava.apis.ImgurApi; 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.OAuthConfig; import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.Verifier; +import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.oauth.OAuth20Service; public class ImgurOAuthServiceImpl extends OAuth20Service { @@ -16,23 +15,25 @@ public ImgurOAuthServiceImpl(DefaultApi20 api, OAuthConfig config) { } @Override - protected T createAccessTokenRequest(Verifier verifier, T request) { + protected OAuthRequest createAccessTokenRequest(String oauthVerifier) { + final DefaultApi20 api = getApi(); + final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); final OAuthConfig config = getConfig(); request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); if (ImgurApi.isOob(config)) { request.addBodyParameter(OAuthConstants.GRANT_TYPE, "pin"); - request.addBodyParameter("pin", verifier.getValue()); + request.addBodyParameter("pin", oauthVerifier); } else { request.addBodyParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.AUTHORIZATION_CODE); - request.addBodyParameter(OAuthConstants.CODE, verifier.getValue()); + request.addBodyParameter(OAuthConstants.CODE, oauthVerifier); } return request; } @Override - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { + public void signRequest(OAuth2AccessToken accessToken, OAuthRequest request) { request.addHeader("Authorization", accessToken == null ? "Client-ID " + getConfig().getApiKey() : "Bearer " + accessToken.getAccessToken()); diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/LinkedIn20ServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/LinkedIn20ServiceImpl.java deleted file mode 100644 index b1d61bb04..000000000 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/LinkedIn20ServiceImpl.java +++ /dev/null @@ -1,30 +0,0 @@ -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.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.Verifier; -import com.github.scribejava.core.oauth.OAuth20Service; - -public class LinkedIn20ServiceImpl extends OAuth20Service { - - public LinkedIn20ServiceImpl(DefaultApi20 api, OAuthConfig config) { - super(api, config); - } - - @Override - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { - request.addQuerystringParameter("oauth2_access_token", accessToken.getAccessToken()); - } - - @Override - protected T createAccessTokenRequest(Verifier verifier, T request) { - super.createAccessTokenRequest(verifier, request); - if (!getConfig().hasGrantType()) { - request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.AUTHORIZATION_CODE); - } - return request; - } -} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/MailruOAuthServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/MailruOAuthServiceImpl.java index 4b78fc6da..3330bb006 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/MailruOAuthServiceImpl.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/MailruOAuthServiceImpl.java @@ -7,11 +7,9 @@ import org.apache.commons.codec.CharEncoding; import static org.apache.commons.codec.digest.DigestUtils.md5Hex; 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.OAuthConfig; -import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.Verifier; +import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.oauth.OAuth20Service; public class MailruOAuthServiceImpl extends OAuth20Service { @@ -21,7 +19,7 @@ public MailruOAuthServiceImpl(DefaultApi20 api, OAuthConfig config) { } @Override - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { + public void signRequest(OAuth2AccessToken accessToken, OAuthRequest request) { // sig = md5(params + secret_key) request.addQuerystringParameter("session_key", accessToken.getAccessToken()); request.addQuerystringParameter("app_id", getConfig().getApiKey()); @@ -50,13 +48,4 @@ public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) throw new IllegalStateException(e); } } - - @Override - protected T createAccessTokenRequest(Verifier verifier, T request) { - super.createAccessTokenRequest(verifier, request); - if (!getConfig().hasGrantType()) { - request.addParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.AUTHORIZATION_CODE); - } - return request; - } } diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OdnoklassnikiServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OdnoklassnikiServiceImpl.java index baca34604..fa9ae2e56 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OdnoklassnikiServiceImpl.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/OdnoklassnikiServiceImpl.java @@ -1,15 +1,22 @@ package com.github.scribejava.apis.service; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import org.apache.commons.codec.CharEncoding; -import static org.apache.commons.codec.digest.DigestUtils.md5Hex; 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.OAuthConfig; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Parameter; +import com.github.scribejava.core.model.ParameterList; import com.github.scribejava.core.oauth.OAuth20Service; +import org.apache.commons.codec.CharEncoding; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.Collections; +import java.util.List; + +import static org.apache.commons.codec.digest.DigestUtils.md5Hex; + public class OdnoklassnikiServiceImpl extends OAuth20Service { public OdnoklassnikiServiceImpl(DefaultApi20 api, OAuthConfig config) { @@ -17,20 +24,24 @@ public OdnoklassnikiServiceImpl(DefaultApi20 api, OAuthConfig config) { } @Override - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { - // sig = md5( request_params_composed_string+ md5(access_token + application_secret_key) ) + public void signRequest(OAuth2AccessToken accessToken, OAuthRequest request) { + //sig = lower(md5( sorted_request_params_composed_string + md5(access_token + application_secret_key))) try { final String tokenDigest = md5Hex(accessToken.getAccessToken() + getConfig().getApiSecret()); - final String completeUrl = request.getCompleteUrl(); - final int queryIndex = completeUrl.indexOf('?'); - if (queryIndex != -1) { - final String sigSource - = URLDecoder.decode(completeUrl.substring(queryIndex + 1).replace("&", ""), CharEncoding.UTF_8) - + tokenDigest; - request.addQuerystringParameter("sig", md5Hex(sigSource)); + final ParameterList queryParams = request.getQueryStringParams(); + queryParams.addAll(request.getBodyParams()); + final List allParams = queryParams.getParams(); + + Collections.sort(allParams); + final StringBuilder builder = new StringBuilder(); + for (Parameter param : allParams) { + builder.append(param.getKey()).append('=').append(param.getValue()); } + final String sigSource = URLDecoder.decode(builder.toString(), CharEncoding.UTF_8) + tokenDigest; + request.addQuerystringParameter("sig", md5Hex(sigSource).toLowerCase()); + super.signRequest(accessToken, request); } catch (UnsupportedEncodingException unex) { throw new IllegalStateException(unex); diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/TutByOAuthServiceImpl.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/TutByOAuthServiceImpl.java index 21a61d13e..f1f14485f 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/service/TutByOAuthServiceImpl.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/service/TutByOAuthServiceImpl.java @@ -1,10 +1,10 @@ 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.OAuth2AccessToken; 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.oauth.OAuth20Service; public class TutByOAuthServiceImpl extends OAuth20Service { @@ -14,7 +14,7 @@ public TutByOAuthServiceImpl(DefaultApi20 api, OAuthConfig config) { } @Override - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { + public void signRequest(OAuth2AccessToken accessToken, OAuthRequest request) { request.addQuerystringParameter(OAuthConstants.TOKEN, accessToken.getAccessToken()); } } diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AWeberExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AWeberExample.java index d1478b901..d304dc6d4 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AWeberExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AWeberExample.java @@ -8,10 +8,11 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class AWeberExample { +public final class AWeberExample { //To get your consumer key/secret, and view API docs, see https://labs.aweber.com/docs private static final String ACCOUNT_RESOURCE_URL = "https://api.aweber.com/1.0/accounts/"; @@ -19,9 +20,11 @@ public abstract class AWeberExample { private static final String CONSUMER_KEY = ""; private static final String CONSUMER_SECRET = ""; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey(CONSUMER_KEY) + private AWeberExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder(CONSUMER_KEY) .apiSecret(CONSUMER_SECRET) .build(AWeberApi.instance()); @@ -40,21 +43,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, ACCOUNT_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, ACCOUNT_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Box20Example.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Box20Example.java new file mode 100644 index 000000000..de8a1c1ed --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Box20Example.java @@ -0,0 +1,90 @@ +package com.github.scribejava.apis.examples; + +import java.util.Random; +import java.util.Scanner; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.apis.BoxApi20; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +public final class Box20Example { + + private static final String NETWORK_NAME = "Box"; + private static final String PROTECTED_RESOURCE_URL = "https://api.box.com/2.0/users/me"; + + private Box20Example() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + //Replace these with your client id and secret + final String clientId = "your client id"; + final String clientSecret = "your client secret"; + final String secretState = "security_token" + new Random().nextInt(999_999); + final OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .state(secretState) + .callback("https://example.com/callback") + .build(BoxApi20.instance()); + final Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + //pass access_type=offline to get refresh token + final Map additionalParams = new HashMap<>(); + additionalParams.put("access_type", "offline"); + //force to reget refresh token (if usera are asked not the first time) + additionalParams.put("prompt", "consent"); + final String authorizationUrl = service.getAuthorizationUrl(additionalParams); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code = in.nextLine(); + System.out.println(); + + System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'."); + System.out.print(">>"); + final String value = in.nextLine(); + if (secretState.equals(value)) { + System.out.println("State value does match!"); + } else { + System.out.println("Ooops, state value does not match!"); + System.out.println("Expected = " + secretState); + System.out.println("Got = " + value); + System.out.println(); + } + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + final OAuth2AccessToken accessToken = service.getAccessToken(code); + System.out.println("Got the Access Token!"); + System.out.println("(If you're curious, it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + final Response response = service.execute(request); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); + } + +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DiggExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DiggExample.java index e0e7ae8cc..aafbea10c 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DiggExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DiggExample.java @@ -8,20 +8,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class DiggExample { +public final class DiggExample { private static final String NETWORK_NAME = "Digg"; private static final String PROTECTED_RESOURCE_URL = "http://services.digg.com/2.0/comment.digg"; - public static void main(String... args) { + private DiggExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "myKey"; final String apiSecret = "mySecret"; - final OAuth10aService service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth10aService service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .build(DiggApi.instance()); final Scanner in = new Scanner(System.in); @@ -43,22 +46,23 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URL); request.addBodyParameter("comment_id", "20100729223726:4fef610331ee46a3b5cbd740bf71313e"); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncNingExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncNingExample.java new file mode 100644 index 000000000..ae8879790 --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncNingExample.java @@ -0,0 +1,95 @@ +package com.github.scribejava.apis.examples; + +import com.github.scribejava.httpclient.ning.NingHttpClientConfig; +import com.ning.http.client.AsyncHttpClientConfig; +import java.util.Random; +import java.util.Scanner; +import java.util.concurrent.ExecutionException; +import com.github.scribejava.apis.FacebookApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; + +public final class FacebookAsyncNingExample { + + private static final String NETWORK_NAME = "Facebook"; + private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/v2.8/me"; + + private FacebookAsyncNingExample() { + } + + public static void main(String... args) throws InterruptedException, ExecutionException, IOException { + // Replace these with your client id and secret + final String clientId = "your client id"; + final String clientSecret = "your client secret"; + final String secretState = "secret" + new Random().nextInt(999_999); + final NingHttpClientConfig clientConfig = new NingHttpClientConfig(new AsyncHttpClientConfig.Builder() + .setMaxConnections(5) + .setRequestTimeout(10_000) + .setAllowPoolingConnections(false) + .setPooledConnectionIdleTimeout(1_000) + .setReadTimeout(1_000) + .build()); + + try (OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .state(secretState) + .callback("http://www.example.com/oauth_callback/") + .httpClientConfig(clientConfig) + .build(FacebookApi.instance())) { + final Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("=== " + NETWORK_NAME + "'s Async OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + final String authorizationUrl = service.getAuthorizationUrl(); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code = in.nextLine(); + System.out.println(); + + System.out.println("And paste the state from server here. We have set 'secretState'='" + + secretState + "'."); + System.out.print(">>"); + final String value = in.nextLine(); + if (secretState.equals(value)) { + System.out.println("State value does match!"); + } else { + System.out.println("Ooops, state value does not match!"); + System.out.println("Expected = " + secretState); + System.out.println("Got = " + value); + System.out.println(); + } + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + final OAuth2AccessToken accessToken = service.getAccessTokenAsync(code).get(); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + final Response response = service.execute(request); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); + } + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookExample.java index 137ec6507..521020e29 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookExample.java @@ -8,25 +8,29 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class FacebookExample { +public final class FacebookExample { private static final String NETWORK_NAME = "Facebook"; - private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/v2.5/me"; + private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/v2.8/me"; - public static void main(String... args) { + private FacebookExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; final String secretState = "secret" + new Random().nextInt(999_999); - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId) + final OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) .state(secretState) .callback("http://www.example.com/oauth_callback/") .build(FacebookApi.instance()); + final Scanner in = new Scanner(System.in, "UTF-8"); System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); @@ -40,7 +44,7 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'."); @@ -57,16 +61,17 @@ public static void main(String... args) { // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FlickrExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FlickrExample.java index 2f6724777..e5809874f 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FlickrExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FlickrExample.java @@ -1,28 +1,33 @@ package com.github.scribejava.apis.examples; -import java.util.Scanner; -import com.github.scribejava.core.builder.ServiceBuilder; import com.github.scribejava.apis.FlickrApi; +import com.github.scribejava.core.builder.ServiceBuilder; import com.github.scribejava.core.model.OAuth1AccessToken; import com.github.scribejava.core.model.OAuth1RequestToken; import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; -public abstract class FlickrExample { +import java.io.IOException; +import java.util.Scanner; +import java.util.concurrent.ExecutionException; + +public final class FlickrExample { private static final String PROTECTED_RESOURCE_URL = "http://api.flickr.com/services/rest/"; - public static void main(String... args) { + private FlickrExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your_app_id"; final String apiSecret = "your_api_secret"; - final OAuth10aService service = new ServiceBuilder() - .apiKey(apiKey) + + final OAuth10aService service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) - .build(FlickrApi.instance()); + .build(FlickrApi.instance(FlickrApi.FlickrPerm.DELETE)); final Scanner in = new Scanner(System.in); System.out.println("=== Flickr's OAuth Workflow ==="); @@ -36,25 +41,26 @@ public static void main(String... args) { System.out.println("Now go and authorize ScribeJava here:"); final String authorizationUrl = service.getAuthorizationUrl(requestToken); - System.out.println(authorizationUrl + "&perms=read"); + System.out.println(authorizationUrl); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); request.addQuerystringParameter("method", "flickr.test.login"); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Foursquare2Example.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Foursquare2Example.java index 17c37f5a9..33e6206ef 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Foursquare2Example.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Foursquare2Example.java @@ -7,20 +7,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class Foursquare2Example { +public final class Foursquare2Example { private static final String PROTECTED_RESOURCE_URL = "https://api.foursquare.com/v2/users/self/friends?oauth_token="; - public static void main(String... args) { + private Foursquare2Example() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your client id"; final String apiSecret = "your client secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth20Service service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .callback("http://localhost:9000/") .build(Foursquare2Api.instance()); @@ -37,22 +40,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getAccessToken(), - service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getAccessToken()); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FoursquareExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FoursquareExample.java index fe6f60e13..afaaca188 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FoursquareExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FoursquareExample.java @@ -8,16 +8,19 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class FoursquareExample { +public final class FoursquareExample { private static final String PROTECTED_RESOURCE_URL = "http://api.foursquare.com/v1/user"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("your client id") + private FoursquareExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("your client id") .apiSecret("your client secret") .build(FoursquareApi.instance()); final Scanner in = new Scanner(System.in); @@ -35,21 +38,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FreelancerExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FreelancerExample.java index a135f94f1..a17f896de 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FreelancerExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FreelancerExample.java @@ -7,12 +7,12 @@ import com.github.scribejava.core.model.OAuth1RequestToken; import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; -import com.github.scribejava.core.model.SignatureType; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class FreelancerExample { +public final class FreelancerExample { private static final String NETWORK_NAME = "Freelancer"; private static final String AUTHORIZE_URL @@ -20,10 +20,11 @@ public abstract class FreelancerExample { private static final String PROTECTED_RESOURCE_URL = "http://api.sandbox.freelancer.com/Job/getJobList.json"; private static final String SCOPE = "http://api.sandbox.freelancer.com"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .signatureType(SignatureType.QueryString) - .apiKey("your client id") + private FreelancerExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("your client id") .apiSecret("your client secret") .scope(SCOPE) .build(FreelancerApi.Sandbox.instance()); @@ -43,22 +44,23 @@ public static void main(String... args) { System.out.println(AUTHORIZE_URL + requestToken.getToken()); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); request.addHeader("GData-Version", "3.0"); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GeniusExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GeniusExample.java new file mode 100644 index 000000000..af515b79c --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GeniusExample.java @@ -0,0 +1,89 @@ +package com.github.scribejava.apis.examples; + +import java.util.Scanner; + +import com.github.scribejava.apis.GeniusApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public final class GeniusExample { + + private static final String NETWORK_NAME = "Genius"; + private static final String PROTECTED_RESOURCE_URL = "https://api.genius.com/songs/378195"; + + private GeniusExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + // Replace these with your client id and secret + final String clientId = "your client id"; + final String clientSecret = "your client secret"; + final String secretState = "100"; + final OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .scope("me") + .state(secretState) + .callback("com.scribejavatest://callback") + .userAgent("ScribeJava") + .build(GeniusApi.instance()); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + final String authorizationUrl = service.getAuthorizationUrl(); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code; + final String value; + try (Scanner in = new Scanner(System.in, "UTF-8")) { + code = in.nextLine(); + System.out.println(); + + System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + + "'."); + System.out.print(">>"); + value = in.nextLine(); + } + + if (secretState.equals(value)) { + System.out.println("State value does match!"); + } else { + System.out.println("Ooops, state value does not match!"); + System.out.println("Expected = " + secretState); + System.out.println("Got = " + value); + System.out.println(); + } + + // Trade the Request Token and Verifier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + final OAuth2AccessToken accessToken = service.getAccessToken(code); + System.out.println("Got the Access Token!"); + System.out.println("(View Access Token contents: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Accessing a protected resource..."); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + final Response response = service.execute(request); + System.out.println("Got it! Viewing contents..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubAsyncOkHttpExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubAsyncOkHttpExample.java new file mode 100644 index 000000000..596a14a45 --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubAsyncOkHttpExample.java @@ -0,0 +1,87 @@ +package com.github.scribejava.apis.examples; + +import com.github.scribejava.apis.GitHubApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import com.github.scribejava.httpclient.okhttp.OkHttpHttpClientConfig; + +import java.io.IOException; +import java.util.Random; +import java.util.Scanner; +import java.util.concurrent.ExecutionException; + +public final class GitHubAsyncOkHttpExample { + + private static final String NETWORK_NAME = "GitHub"; + private static final String PROTECTED_RESOURCE_URL = "https://api.github.com/user"; + + private GitHubAsyncOkHttpExample() { + } + + public static void main(String... args) throws IOException, ExecutionException, InterruptedException { + // Replace these with your client id and secret + final String clientId = "your client id"; + final String clientSecret = "your client secret"; + final String secretState = "secret" + new Random().nextInt(999_999); + try (OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .state(secretState) + .callback("http://www.example.com/oauth_callback/") + .httpClientConfig(OkHttpHttpClientConfig.defaultConfig()) + .build(GitHubApi.instance())) { + final Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + final String authorizationUrl = service.getAuthorizationUrl(); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code = in.nextLine(); + System.out.println(); + + System.out.println("And paste the state from server here. We have set 'secretState'='" + + secretState + "'."); + System.out.print(">>"); + final String value = in.nextLine(); + if (secretState.equals(value)) { + System.out.println("State value does match!"); + } else { + System.out.println("Ooops, state value does not match!"); + System.out.println("Expected = " + secretState); + System.out.println("Got = " + value); + System.out.println(); + } + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + final OAuth2AccessToken accessToken = service.getAccessToken(code); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + final Response response = service.execute(request); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); + } + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubExample.java index 889c505a8..8c3444d92 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubExample.java @@ -8,21 +8,24 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class GitHubExample { +public final class GitHubExample { private static final String NETWORK_NAME = "GitHub"; private static final String PROTECTED_RESOURCE_URL = "https://api.github.com/user"; - public static void main(String... args) { + private GitHubExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; final String secretState = "secret" + new Random().nextInt(999_999); - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId) + final OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) .state(secretState) .callback("http://www.example.com/oauth_callback/") @@ -40,7 +43,7 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'."); @@ -57,16 +60,17 @@ public static void main(String... args) { // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20AsyncAHCExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20AsyncAHCExample.java new file mode 100644 index 000000000..7ac82e7e9 --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20AsyncAHCExample.java @@ -0,0 +1,124 @@ +package com.github.scribejava.apis.examples; + +import java.util.Random; +import java.util.Scanner; +import com.github.scribejava.apis.GoogleApi20; +import com.github.scribejava.httpclient.ahc.AhcHttpClientConfig; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.httpclient.HttpClientConfig; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import org.asynchttpclient.DefaultAsyncHttpClientConfig; + +public final class Google20AsyncAHCExample { + + private static final String NETWORK_NAME = "G+ Async"; + private static final String PROTECTED_RESOURCE_URL = "https://www.googleapis.com/plus/v1/people/me"; + + private Google20AsyncAHCExample() { + } + + public static void main(String... args) throws InterruptedException, ExecutionException, IOException { + // Replace these with your client id and secret + final String clientId = "your client id"; + final String clientSecret = "your client secret"; + final String secretState = "secret" + new Random().nextInt(999_999); + final HttpClientConfig clientConfig = new AhcHttpClientConfig(new DefaultAsyncHttpClientConfig.Builder() + .setMaxConnections(5) + .setRequestTimeout(10_000) + .setPooledConnectionIdleTimeout(1_000) + .setReadTimeout(1_000) + .build()); + + try (OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .scope("profile") // replace with desired scope + .state(secretState) + .callback("http://example.com/callback") + .httpClientConfig(clientConfig) + .build(GoogleApi20.instance())) { + final Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + //pass access_type=offline to get refresh token + //https://developers.google.com/identity/protocols/OAuth2WebServer#preparing-to-start-the-oauth-20-flow + final Map additionalParams = new HashMap<>(); + additionalParams.put("access_type", "offline"); + //force to reget refresh token (if usera are asked not the first time) + additionalParams.put("prompt", "consent"); + final String authorizationUrl = service.getAuthorizationUrl(additionalParams); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code = in.nextLine(); + System.out.println(); + + System.out.println("And paste the state from server here. We have set 'secretState'='" + + secretState + "'."); + System.out.print(">>"); + final String value = in.nextLine(); + if (secretState.equals(value)) { + System.out.println("State value does match!"); + } else { + System.out.println("Ooops, state value does not match!"); + System.out.println("Expected = " + secretState); + System.out.println("Got = " + value); + System.out.println(); + } + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + OAuth2AccessToken accessToken = service.getAccessToken(code); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + + System.out.println("Refreshing the Access Token..."); + accessToken = service.refreshAccessToken(accessToken.getRefreshToken()); + System.out.println("Refreshed the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + while (true) { + System.out.println("Paste fieldnames to fetch (leave empty to get profile, 'exit' to stop example)"); + System.out.print(">>"); + final String query = in.nextLine(); + System.out.println(); + + final String requestUrl; + if ("exit".equals(query)) { + break; + } else if (query == null || query.isEmpty()) { + requestUrl = PROTECTED_RESOURCE_URL; + } else { + requestUrl = PROTECTED_RESOURCE_URL + "?fields=" + query; + } + + final OAuthRequest request = new OAuthRequest(Verb.GET, requestUrl); + service.signRequest(accessToken, request); + final Response response = service.execute(request); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + } + } + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java index f4fc5dec3..e9e2adf27 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java @@ -8,21 +8,26 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; -public abstract class Google20Example { +public final class Google20Example { private static final String NETWORK_NAME = "G+"; private static final String PROTECTED_RESOURCE_URL = "https://www.googleapis.com/plus/v1/people/me"; - public static void main(String... args) { + private Google20Example() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; final String secretState = "secret" + new Random().nextInt(999_999); - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId) + final OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) .scope("profile") // replace with desired scope .state(secretState) @@ -35,13 +40,19 @@ public static void main(String... args) { // Obtain the Authorization URL System.out.println("Fetching the Authorization URL..."); - final String authorizationUrl = service.getAuthorizationUrl(); + //pass access_type=offline to get refresh token + //https://developers.google.com/identity/protocols/OAuth2WebServer#preparing-to-start-the-oauth-20-flow + final Map additionalParams = new HashMap<>(); + additionalParams.put("access_type", "offline"); + //force to reget refresh token (if usera are asked not the first time) + additionalParams.put("prompt", "consent"); + final String authorizationUrl = service.getAuthorizationUrl(additionalParams); System.out.println("Got the Authorization URL!"); System.out.println("Now go and authorize ScribeJava here:"); System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'."); @@ -58,9 +69,16 @@ public static void main(String... args) { // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + + System.out.println("Refreshing the Access Token..."); + accessToken = service.refreshAccessToken(accessToken.getRefreshToken()); + System.out.println("Refreshed the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! @@ -80,9 +98,9 @@ public static void main(String... args) { requestUrl = PROTECTED_RESOURCE_URL + "?fields=" + query; } - final OAuthRequest request = new OAuthRequest(Verb.GET, requestUrl, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, requestUrl); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println(); System.out.println(response.getCode()); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GoogleExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GoogleExample.java deleted file mode 100644 index 19e249d9f..000000000 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GoogleExample.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.github.scribejava.apis.examples; - -import java.util.Scanner; -import com.github.scribejava.core.builder.ServiceBuilder; -import com.github.scribejava.apis.GoogleApi; -import com.github.scribejava.core.model.OAuth1AccessToken; -import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.model.OAuthRequest; -import com.github.scribejava.core.model.Response; -import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; -import com.github.scribejava.core.oauth.OAuth10aService; - -public abstract class GoogleExample { - - private static final String NETWORK_NAME = "Google"; - private static final String AUTHORIZE_URL = "https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token="; - private static final String PROTECTED_RESOURCE_URL = "https://docs.google.com/feeds/default/private/full/"; - private static final String SCOPE = "https://docs.google.com/feeds/"; - - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("anonymous") - .apiSecret("anonymous") - .scope(SCOPE) - .build(GoogleApi.instance()); - final Scanner in = new Scanner(System.in); - - System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); - System.out.println(); - - // Obtain the Request Token - System.out.println("Fetching the Request Token..."); - final OAuth1RequestToken requestToken = service.getRequestToken(); - System.out.println("Got the Request Token!"); - System.out.println("(if your curious it looks like this: " + requestToken + " )"); - System.out.println(); - - System.out.println("Now go and authorize ScribeJava here:"); - System.out.println(AUTHORIZE_URL + requestToken.getToken()); - System.out.println("And paste the verifier here"); - System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); - System.out.println(); - - // Trade the Request Token and Verfier for the Access Token - System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); - System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); - System.out.println(); - - // Now let's go and ask for a protected resource! - System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); - service.signRequest(accessToken, request); - request.addHeader("GData-Version", "3.0"); - final Response response = request.send(); - System.out.println("Got it! Lets see what we found..."); - System.out.println(); - System.out.println(response.getCode()); - System.out.println(response.getBody()); - - System.out.println(); - System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); - - } -} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/HHExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/HHExample.java index 9e91e301e..e892eace3 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/HHExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/HHExample.java @@ -6,26 +6,28 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.apis.HHApi; import com.github.scribejava.core.model.OAuth2AccessToken; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class HHExample { +public final class HHExample { private static final String NETWORK_NAME = "hh.ru"; private static final String PROTECTED_RESOURCE_URL = "https://api.hh.ru/me"; - public static void main(String... args) { + private HHExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId) + final OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) .callback("http://your.site.com/callback") - .grantType("authorization_code") .build(HHApi.instance()); final Scanner in = new Scanner(System.in); @@ -40,20 +42,21 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ImgurExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ImgurExample.java index fd3870708..35f6d9a31 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ImgurExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ImgurExample.java @@ -6,22 +6,25 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; import java.util.Scanner; +import java.util.concurrent.ExecutionException; -public abstract class ImgurExample { +public final class ImgurExample { private static final String NETWORK_NAME = "Imgur"; private static final String PROTECTED_RESOURCE_URL = "https://api.imgur.com/3/account/me"; - public static void main(String... args) { + private ImgurExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your client id"; final String apiSecret = "your client secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth20Service service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .build(ImgurApi.instance()); final Scanner in = new Scanner(System.in); @@ -37,21 +40,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verifier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Kaixin20Example.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Kaixin20Example.java index 3f79d4d51..6d61a613b 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Kaixin20Example.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Kaixin20Example.java @@ -7,20 +7,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class Kaixin20Example { +public final class Kaixin20Example { private static final String NETWORK_NAME = "Kaixin"; private static final String PROTECTED_RESOURCE_URL = "https://api.kaixin001.com/users/me.json"; - public static void main(String... args) { + private Kaixin20Example() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your api key"; final String apiSecret = "your api secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth20Service service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .callback("http://your.domain.com/handle") .build(KaixinApi20.instance()); @@ -37,21 +40,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verifier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedIn20Example.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedIn20Example.java index 2232e3dc8..8553c3498 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedIn20Example.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedIn20Example.java @@ -7,21 +7,25 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class LinkedIn20Example { +public final class LinkedIn20Example { private static final String NETWORK_NAME = "LinkedIn"; private static final String PROTECTED_RESOURCE_URL = "https://api.linkedin.com/v1/people/~:(%s)"; - public static void main(String... args) { + private LinkedIn20Example() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId).apiSecret(clientSecret) - .scope("r_basicprofile,r_emailaddress") // replace with desired scope + final OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .scope("r_basicprofile r_emailaddress") // replace with desired scope .callback("http://example.com/callback") .state("some_params") .build(LinkedInApi20.instance()); @@ -38,14 +42,15 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! @@ -60,12 +65,11 @@ public static void main(String... args) { break; } - final OAuthRequest request = new OAuthRequest(Verb.GET, String.format(PROTECTED_RESOURCE_URL, query), - service); + final OAuthRequest request = new OAuthRequest(Verb.GET, String.format(PROTECTED_RESOURCE_URL, query)); request.addHeader("x-li-format", "json"); request.addHeader("Accept-Language", "ru-RU"); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println(); System.out.println(response.getCode()); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExample.java index e026c969a..02ae520c1 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExample.java @@ -8,17 +8,20 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class LinkedInExample { +public final class LinkedInExample { private static final String PROTECTED_RESOURCE_URL = "http://api.linkedin.com/v1/people/~/connections:(id,last-name)"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("your client id") + private LinkedInExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("your client id") .apiSecret("your client secret") .build(LinkedInApi.instance()); final Scanner in = new Scanner(System.in); @@ -36,21 +39,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExampleWithScopes.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExampleWithScopes.java index e24d39747..a8247f65c 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExampleWithScopes.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExampleWithScopes.java @@ -8,23 +8,26 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class LinkedInExampleWithScopes { +public final class LinkedInExampleWithScopes { private static final String PROTECTED_RESOURCE_URL = "http://api.linkedin.com/v1/people/~/connections:(id,last-name)"; - public static void main(String... args) { + private LinkedInExampleWithScopes() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client id"; - final OAuth10aService service = new ServiceBuilder() - .apiKey(clientId) + final OAuth10aService service = new ServiceBuilder(clientId) .apiSecret(clientSecret) - .build(new LinkedInApi("foo", "bar", "baz")); + .build(LinkedInApi.instance("foo", "bar", "baz")); final Scanner in = new Scanner(System.in); System.out.println("=== LinkedIn's OAuth Workflow ==="); @@ -40,21 +43,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LiveExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LiveExample.java index 199bb111a..c693b0e73 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LiveExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LiveExample.java @@ -7,20 +7,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class LiveExample { +public final class LiveExample { private static final String PROTECTED_RESOURCE_URL = "https://api.foursquare.com/v2/users/self/friends?oauth_token="; - public static void main(String... args) { + private LiveExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = ""; final String apiSecret = ""; - final OAuth20Service service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth20Service service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .scope("wl.basic") .callback("http://localhost:9000/") @@ -38,22 +41,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getAccessToken(), - service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getAccessToken()); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruAsyncExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruAsyncExample.java index f0824d2a7..2c566e99b 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruAsyncExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruAsyncExample.java @@ -1,78 +1,81 @@ package com.github.scribejava.apis.examples; +import com.github.scribejava.httpclient.ning.NingHttpClientConfig; import com.ning.http.client.AsyncHttpClientConfig; import java.util.Scanner; import java.util.concurrent.ExecutionException; import com.github.scribejava.apis.MailruApi; -import com.github.scribejava.core.builder.ServiceBuilderAsync; +import com.github.scribejava.core.builder.ServiceBuilder; import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuthRequestAsync; +import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; -public abstract class MailruAsyncExample { +public final class MailruAsyncExample { private static final String NETWORK_NAME = "Mail.ru"; private static final String PROTECTED_RESOURCE_URL = "http://www.appsmail.ru/platform/api?method=users.getInfo&secure=1"; - public static void main(String... args) throws InterruptedException, ExecutionException { + private MailruAsyncExample() { + } + + public static void main(String... args) throws InterruptedException, ExecutionException, IOException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; - final AsyncHttpClientConfig clientConfig = new AsyncHttpClientConfig.Builder() + final NingHttpClientConfig clientConfig = new NingHttpClientConfig(new AsyncHttpClientConfig.Builder() .setMaxConnections(5) .setRequestTimeout(10_000) .setAllowPoolingConnections(false) .setPooledConnectionIdleTimeout(1_000) .setReadTimeout(10_000) - .build(); + .build()); - final OAuth20Service service = new ServiceBuilderAsync() - .apiKey(clientId) + try (OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) .callback("http://www.example.com/oauth_callback/") - .asyncHttpClientConfig(clientConfig) - .build(MailruApi.instance()); - - final Scanner in = new Scanner(System.in, "UTF-8"); + .httpClientConfig(clientConfig) + .build(MailruApi.instance())) { + final Scanner in = new Scanner(System.in, "UTF-8"); - System.out.println("=== " + NETWORK_NAME + "'s Async OAuth Workflow ==="); - System.out.println(); + System.out.println("=== " + NETWORK_NAME + "'s Async OAuth Workflow ==="); + System.out.println(); - // Obtain the Authorization URL - System.out.println("Fetching the Authorization URL..."); - final String authorizationUrl = service.getAuthorizationUrl(); - System.out.println("Got the Authorization URL!"); - System.out.println("Now go and authorize ScribeJava here:"); - System.out.println(authorizationUrl); - System.out.println("And paste the authorization code here"); - System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); - System.out.println(); + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + final String authorizationUrl = service.getAuthorizationUrl(); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code = in.nextLine(); + System.out.println(); - // Trade the Request Token and Verfier for the Access Token - System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessTokenAsync(verifier, null).get(); - System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); - System.out.println(); + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + final OAuth2AccessToken accessToken = service.getAccessToken(code); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); - System.out.println("Now we're going to access a protected resource..."); - final OAuthRequestAsync request = new OAuthRequestAsync(Verb.GET, PROTECTED_RESOURCE_URL, service); - service.signRequest(accessToken, request); - final Response response = request.sendAsync(null).get(); + System.out.println("Now we're going to access a protected resource..."); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + final Response response = service.execute(request); - System.out.println("Got it! Lets see what we found..."); - System.out.println(); - System.out.println(response.getCode()); - System.out.println(response.getBody()); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); - System.out.println(); - System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); - service.closeAsyncClient(); + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); + } } } diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruExample.java index 6e0ac27c8..f6c620d0f 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruExample.java @@ -5,23 +5,26 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.apis.MailruApi; import com.github.scribejava.core.model.OAuth2AccessToken; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class MailruExample { +public final class MailruExample { private static final String NETWORK_NAME = "Mail.ru"; private static final String PROTECTED_RESOURCE_URL = "http://www.appsmail.ru/platform/api?method=users.getInfo&secure=1"; - public static void main(String... args) { + private MailruExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId) + final OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) .callback("http://www.example.com/oauth_callback/") .build(MailruApi.instance()); @@ -39,20 +42,21 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MeetupExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MeetupExample.java index 6a19c459d..c8d6ea911 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MeetupExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MeetupExample.java @@ -8,16 +8,19 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class MeetupExample { +public final class MeetupExample { private static final String PROTECTED_RESOURCE_URL = "http://api.meetup.com/2/member/self"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("your client id") + private MeetupExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("your client id") .apiSecret("your client secret") .build(MeetupApi.instance()); final Scanner in = new Scanner(System.in); @@ -35,21 +38,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LoveFilmExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MisfitExample.java similarity index 57% rename from scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LoveFilmExample.java rename to scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MisfitExample.java index 46db1f3ba..ed6c1dd7f 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LoveFilmExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MisfitExample.java @@ -1,63 +1,64 @@ package com.github.scribejava.apis.examples; -import java.util.Scanner; +import com.github.scribejava.apis.MisfitApi; import com.github.scribejava.core.builder.ServiceBuilder; -import com.github.scribejava.apis.LoveFilmApi; -import com.github.scribejava.core.model.OAuth1AccessToken; -import com.github.scribejava.core.model.OAuth1RequestToken; +import com.github.scribejava.core.model.OAuth2AccessToken; import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; -import com.github.scribejava.core.oauth.OAuth10aService; +import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; + +import java.util.Scanner; +import java.util.concurrent.ExecutionException; -public abstract class LoveFilmExample { +public final class MisfitExample { - private static final String NETWORK_NAME = "LoveFilm"; - private static final String PROTECTED_RESOURCE_URL = "https://api.lovefilm.com/users"; + private static final String NETWORK_NAME = "Misfit"; + private static final String PROTECTED_RESOURCE_URL + = "https://api.misfitwearables.com/move/resource/v1/user/me/profile"; - public static void main(String... args) { + private MisfitExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret - final String apiKey = "your_key"; - final String apiSecret = "your_secret"; - final OAuth10aService service = new ServiceBuilder() - .apiKey(apiKey) + final String apiKey = "your client id"; + final String apiSecret = "your client secret"; + final OAuth20Service service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) - .build(LoveFilmApi.instance()); + .callback("http://example.com/callback/") + .scope("public,birthday,email,tracking,session,sleep") + .build(MisfitApi.instance()); final Scanner in = new Scanner(System.in); System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); System.out.println(); - // Grab a request token. - System.out.println("Fetching request token."); - final OAuth1RequestToken requestToken = service.getRequestToken(); - System.out.println("Got it ... "); - System.out.println(requestToken.getToken()); - // Obtain the Authorization URL System.out.println("Fetching the Authorization URL..."); - final String authorizationUrl = service.getAuthorizationUrl(requestToken); + final String authorizationUrl = service.getAuthorizationUrl(); System.out.println("Got the Authorization URL!"); System.out.println("Now go and authorize ScribeJava here:"); System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); - // Trade the Request Token and Verfier for the Access Token + // Trade the Request Token and Verifier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); @@ -65,6 +66,5 @@ public static void main(String... args) { System.out.println(); System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); - } } diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/NaverExample.java similarity index 62% rename from scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncExample.java rename to scribejava-apis/src/test/java/com/github/scribejava/apis/examples/NaverExample.java index d610596ab..5d2d5548e 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/NaverExample.java @@ -1,50 +1,40 @@ package com.github.scribejava.apis.examples; -import com.ning.http.client.AsyncHttpClientConfig; -import java.util.Random; -import java.util.Scanner; -import java.util.concurrent.ExecutionException; -import com.github.scribejava.apis.FacebookApi; -import com.github.scribejava.core.builder.ServiceBuilderAsync; -import com.github.scribejava.core.model.ForceTypeOfHttpRequest; +import com.github.scribejava.apis.NaverApi; +import com.github.scribejava.core.builder.ServiceBuilder; import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuthRequestAsync; +import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; -import com.github.scribejava.core.model.ScribeJavaConfig; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; -public abstract class FacebookAsyncExample { +import java.io.IOException; +import java.util.Random; +import java.util.Scanner; +import java.util.concurrent.ExecutionException; - private static final String NETWORK_NAME = "Facebook"; - private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/v2.5/me"; +public final class NaverExample { - public static void main(String... args) throws InterruptedException, ExecutionException { + private static final String NETWORK_NAME = "Naver"; + private static final String PROTECTED_RESOURCE_URL = "https://openapi.naver.com/v1/nid/me"; + + private NaverExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; final String secretState = "secret" + new Random().nextInt(999_999); - ScribeJavaConfig.setForceTypeOfHttpRequests(ForceTypeOfHttpRequest.FORCE_ASYNC_ONLY_HTTP_REQUESTS); - final AsyncHttpClientConfig clientConfig = new AsyncHttpClientConfig.Builder() - .setMaxConnections(5) - .setRequestTimeout(10_000) - .setAllowPoolingConnections(false) - .setPooledConnectionIdleTimeout(1_000) - .setReadTimeout(1_000) - .build(); - - final OAuth20Service service = new ServiceBuilderAsync() - .apiKey(clientId) + final OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) .state(secretState) .callback("http://www.example.com/oauth_callback/") - .asyncHttpClientConfig(clientConfig) - .build(FacebookApi.instance()); + .build(NaverApi.instance()); final Scanner in = new Scanner(System.in, "UTF-8"); - System.out.println("=== " + NETWORK_NAME + "'s Async OAuth Workflow ==="); + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); System.out.println(); // Obtain the Authorization URL @@ -55,7 +45,7 @@ public static void main(String... args) throws InterruptedException, ExecutionEx System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'."); @@ -72,16 +62,17 @@ public static void main(String... args) throws InterruptedException, ExecutionEx // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessTokenAsync(verifier, null).get(); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequestAsync request = new OAuthRequestAsync(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.sendAsync(null).get(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); @@ -89,6 +80,6 @@ public static void main(String... args) throws InterruptedException, ExecutionEx System.out.println(); System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); - service.closeAsyncClient(); + } } diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/NeteaseWeiboExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/NeteaseWeiboExample.java index e5130908f..866c2167b 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/NeteaseWeiboExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/NeteaseWeiboExample.java @@ -8,20 +8,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class NeteaseWeiboExample { +public final class NeteaseWeiboExample { private static final String NETWORK_NAME = "NetEase(163.com) Weibo"; private static final String PROTECTED_RESOURCE_URL = "http://api.t.163.com/account/verify_credentials.json"; - public static void main(String... args) { + private NeteaseWeiboExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your key"; final String apiSecret = "your secret"; - final OAuth10aService service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth10aService service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .build(NeteaseWeibooApi.instance()); final Scanner in = new Scanner(System.in); @@ -43,22 +46,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " - + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OdnoklassnikiExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OdnoklassnikiExample.java index a7b1b9710..8ea048fe8 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OdnoklassnikiExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OdnoklassnikiExample.java @@ -4,30 +4,30 @@ import com.github.scribejava.core.builder.ServiceBuilder; import com.github.scribejava.apis.OdnoklassnikiApi; import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.model.OAuthConstants; import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class OdnoklassnikiExample { +public final class OdnoklassnikiExample { private static final String NETWORK_NAME = "Odnoklassniki.ru"; private static final String PROTECTED_RESOURCE_URL - = "http://api.odnoklassniki.ru/api/users/getCurrentUser?application_key=%1$s&format=JSON"; + = "https://api.ok.ru/api/users/getCurrentUser?application_key=%1$s&format=JSON"; - public static void main(String... args) { + private OdnoklassnikiExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret - final String clientId = "your client id"; - final String publicKey = "your api secret"; - final String clientSecret = "your client secret"; + final String clientId = "your api client id"; + final String publicKey = "your api public key"; + final String secretKey = "your api secret key"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId) - .apiSecret(clientSecret) - .scope("VALUABLE ACCESS") - .grantType(OAuthConstants.AUTHORIZATION_CODE) + final OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(secretKey) .callback("http://your.site.com/callback") .build(OdnoklassnikiApi.instance()); @@ -44,23 +44,30 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); + + System.out.println("Refreshing the Access Token..."); + accessToken = service.refreshAccessToken(accessToken.getRefreshToken()); + System.out.println("Refreshed the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, String.format(PROTECTED_RESOURCE_URL, publicKey), - service); + final OAuthRequest request = new OAuthRequest(Verb.GET, String.format(PROTECTED_RESOURCE_URL, publicKey)); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/PinterestExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/PinterestExample.java index 3860ebfb4..1fec439b4 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/PinterestExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/PinterestExample.java @@ -6,21 +6,24 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; import java.util.Scanner; +import java.util.concurrent.ExecutionException; -public abstract class PinterestExample { +public final class PinterestExample { private static final String PROTECTED_RESOURCE_URL = "https://api.pinterest.com/v1/me/?access_token?access_token="; - public static void main(String... args) { + private PinterestExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your_app_id"; final String apiSecret = "your_app_secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth20Service service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .scope("read_public,write_public,read_relationships,write_relationships") .callback("https://localhost:9000/") // Add as valid callback in developer portal @@ -38,22 +41,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getAccessToken(), - service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL + accessToken.getAccessToken()); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Px500Example.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Px500Example.java index 9d366e38d..820a0e821 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Px500Example.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Px500Example.java @@ -8,16 +8,19 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class Px500Example { +public final class Px500Example { private static final String PROTECTED_RESOURCE_URL = "https://api.500px.com/v1/"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("your-api-key") + private Px500Example() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("your-api-key") .apiSecret("your-api-secret") .build(Px500Api.instance()); final Scanner in = new Scanner(System.in); @@ -35,21 +38,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/RenrenExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/RenrenExample.java index 48f37ad17..1eea7e581 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/RenrenExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/RenrenExample.java @@ -16,20 +16,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class RenrenExample { +public final class RenrenExample { private static final String NETWORK_NAME = "Renren"; private static final String PROTECTED_RESOURCE_URL = "http://api.renren.com/restserver.do"; - public static void main(String... args) { + private RenrenExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your api key"; final String apiSecret = "your api secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth20Service service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .scope("status_update publish_feed") .callback("http://your.doman.com/oauth/renren") @@ -47,19 +50,20 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URL); final Map parameters = new HashMap<>(); parameters.put("method", "users.getInfo"); parameters.put("format", "json"); @@ -80,7 +84,7 @@ public static void main(String... args) { System.out.println("Sig string: " + b.toString()); request.addQuerystringParameter("sig", md5(b.toString())); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceExample.java new file mode 100644 index 000000000..30f4aab85 --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceExample.java @@ -0,0 +1,103 @@ +package com.github.scribejava.apis.examples; + +import java.io.IOException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Scanner; + +import com.github.scribejava.apis.SalesforceApi; +import com.github.scribejava.apis.salesforce.SalesforceToken; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.concurrent.ExecutionException; + +public final class SalesforceExample { + + private static final String NETWORK_NAME = "Salesforce"; + + private SalesforceExample() { + } + + public static void main(String... args) throws IOException, NoSuchAlgorithmException, KeyManagementException, + InterruptedException, ExecutionException { + // Replace these with your client id and secret + final String clientId = "your client id"; + final String clientSecret = "your client secret"; + //IT's important! Salesforce upper require TLS v1.1 or 1.2. + //They are enabled in Java 8 by default, but not in Java 7 + SalesforceApi.initTLSv11orUpper(); + + // The below used ServiceBuilder connects to login.salesforce.com + // (production environment). + // + // When you plan to connect to a Sandbox environment you've to use SalesforceApi.sandbox() API instance + // new ServiceBuilder.....build(SalesforceApi.sandbox()); + + final OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .callback("https://www.example.com/callback") + .build(SalesforceApi.instance()); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth20 Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + final String authorizationUrl = service.getAuthorizationUrl(); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code; + try (Scanner in = new Scanner(System.in)) { + code = in.nextLine(); + } + System.out.println(); + + // The code needs to be URL decoded + final String codeEncoded = URLDecoder.decode(code, "UTF-8"); + + // Trade the Request Token and Verifier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + + final OAuth2AccessToken accessToken = service.getAccessToken(codeEncoded); + final SalesforceToken salesforceAccessToken; + if (accessToken instanceof SalesforceToken) { + salesforceAccessToken = (SalesforceToken) accessToken; + } else { + throw new IllegalStateException("Salesforce API didn't return SalesforceToken."); + } + System.out.println("Got the Access Token!"); + + System.out.println("(if your curious it looks like this: " + salesforceAccessToken + ", 'rawResponse'='" + + accessToken.getRawResponse() + "')"); + System.out.println(); + + System.out.println("instance_url is: " + salesforceAccessToken.getInstanceUrl()); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're reading accounts from the Salesforce org (maxing them to 10)."); + + // Sample SOQL statement + final String queryEncoded = URLEncoder.encode("Select Id, Name from Account LIMIT 10", "UTF-8"); + + // Building the query URI. We've parsed the instance URL from the accessToken request. + final String url = salesforceAccessToken.getInstanceUrl() + "/services/data/v36.0/query?q=" + queryEncoded; + + System.out.println(); + System.out.println("Full URL: " + url); + + final OAuthRequest request = new OAuthRequest(Verb.GET, url); + final Response response = service.execute(request); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceNingAsyncExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceNingAsyncExample.java new file mode 100644 index 000000000..d057df0d9 --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceNingAsyncExample.java @@ -0,0 +1,100 @@ +package com.github.scribejava.apis.examples; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Scanner; +import java.util.concurrent.ExecutionException; + +import com.github.scribejava.apis.SalesforceApi; +import com.github.scribejava.apis.salesforce.SalesforceToken; +import com.github.scribejava.httpclient.ning.NingHttpClientConfig; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import com.ning.http.client.AsyncHttpClientConfig; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +public final class SalesforceNingAsyncExample { + + private static final String NETWORK_NAME = "Salesforce"; + + private SalesforceNingAsyncExample() { + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + public static void main(String... args) throws InterruptedException, ExecutionException, + UnsupportedEncodingException, IOException, NoSuchAlgorithmException, KeyManagementException { + // Replace these with your client id and secret + final String clientId = "your client id"; + final String clientSecret = "your client secret"; + + final NingHttpClientConfig clientConfig = new NingHttpClientConfig(new AsyncHttpClientConfig.Builder() + .setMaxConnections(5) + .setRequestTimeout(10_000) + .setAllowPoolingConnections(false) + .setPooledConnectionIdleTimeout(1_000) + .setReadTimeout(10_000) + .build()); + + //IT's important! Salesforce upper require TLS v1.1 or 1.2 + SalesforceApi.initTLSv11orUpper(); + try (OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .httpClientConfig(clientConfig) + .callback("https://www.example.com/callback") + .build(SalesforceApi.instance())) { + System.out.println("=== " + NETWORK_NAME + "'s OAuth20 Workflow ==="); + System.out.println(); + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + final String authorizationUrl = service.getAuthorizationUrl(); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code; + try (Scanner in = new Scanner(System.in)) { + code = in.nextLine(); + } + System.out.println(); + final String codeEncoded = URLDecoder.decode(code, "UTF-8"); + // Trade the Request Token and Verifier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + + final OAuth2AccessToken accessToken = service.getAccessToken(codeEncoded); + final SalesforceToken salesforceAccessToken; + if (accessToken instanceof SalesforceToken) { + salesforceAccessToken = (SalesforceToken) accessToken; + } else { + throw new IllegalStateException("Salesforce API didn't return SalesforceToken."); + } + System.out.println("Got the Access Token!"); + + System.out.println("(if your curious it looks like this: " + salesforceAccessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); + System.out.println("Instance is: " + salesforceAccessToken.getInstanceUrl()); + // Now let's go and ask for a protected resource! + System.out.println("Now we're reading accounts from the Salesforce org (maxing them to 10)."); + // Sample SOQL statement + final String queryEncoded = URLEncoder.encode("Select Id, Name from Account LIMIT 10", "UTF-8"); + // Building the query URI. We've parsed the instance URL from the + // accessToken request. + final String url = salesforceAccessToken.getInstanceUrl() + "/services/data/v36.0/query?q=" + queryEncoded; + System.out.println(); + System.out.println("Full URL: " + url); + final OAuthRequest request = new OAuthRequest(Verb.GET, url); + final Response response = service.execute(request); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + } + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeibo2Example.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeibo2Example.java index 33e46454e..a2bacaff4 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeibo2Example.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeibo2Example.java @@ -7,20 +7,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class SinaWeibo2Example { +public final class SinaWeibo2Example { private static final String NETWORK_NAME = "SinaWeibo"; private static final String PROTECTED_RESOURCE_URL = "https://api.weibo.com/2/account/get_uid.json"; - public static void main(String... args) { + private SinaWeibo2Example() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your_api_key"; final String apiSecret = "your_api_secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth20Service service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .callback("http://www.dajie.com/oauth/sina") .build(SinaWeiboApi20.instance()); @@ -37,21 +40,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verifier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeiboExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeiboExample.java index f6ddf99e2..289f4eb50 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeiboExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeiboExample.java @@ -8,20 +8,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class SinaWeiboExample { +public final class SinaWeiboExample { private static final String NETWORK_NAME = "SinaWeibo"; private static final String PROTECTED_RESOURCE_URL = "http://api.t.sina.com.cn/account/verify_credentials.json"; - public static void main(String... args) { + private SinaWeiboExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your key"; final String apiSecret = "your secret"; - final OAuth10aService service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth10aService service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .build(SinaWeiboApi.instance()); final Scanner in = new Scanner(System.in); @@ -43,22 +46,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " - + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SkyrockExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SkyrockExample.java index 3c0a8655a..fcb2f592a 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SkyrockExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SkyrockExample.java @@ -8,16 +8,19 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class SkyrockExample { +public final class SkyrockExample { private static final String PROTECTED_RESOURCE_URL = "https://api.skyrock.com/v2/user/get.json"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("your-api-key") + private SkyrockExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("your-api-key") .apiSecret("your-api-secret") .build(SkyrockApi.instance()); final Scanner in = new Scanner(System.in); @@ -35,21 +38,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SohuWeiboExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SohuWeiboExample.java index 3f39264fa..0cb93b91a 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SohuWeiboExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SohuWeiboExample.java @@ -8,20 +8,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class SohuWeiboExample { +public final class SohuWeiboExample { private static final String NETWORK_NAME = "SohuWeibo"; private static final String PROTECTED_RESOURCE_URL = "http://api.t.sohu.com/account/verify_credentials.json"; - public static void main(String... args) { + private SohuWeiboExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your_key"; final String apiSecret = "your_secret"; - final OAuth10aService service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth10aService service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .build(SohuWeiboApi.instance()); final Scanner in = new Scanner(System.in); @@ -43,22 +46,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " - + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/StackExchangeExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/StackExchangeExample.java index c6f8a4288..04858eab6 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/StackExchangeExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/StackExchangeExample.java @@ -9,15 +9,19 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class StackExchangeExample { +public final class StackExchangeExample { private static final String NETWORK_NAME = "Stack Exchange"; private static final String PROTECTED_RESOURCE_URL = "https://api.stackexchange.com/2.2/me"; - public static void main(String... args) { + private StackExchangeExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id, secret, application key and // optionally site name final String clientId = "your client id"; @@ -26,8 +30,7 @@ public static void main(String... args) { // Enter one of Stack Exchange site names the user has account with. final String site = "stackoverflow"; final String secretState = "secret" + new Random().nextInt(999_999); - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId) + final OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) .state(secretState) .callback("http://www.example.com/oauth_callback/") @@ -45,7 +48,7 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'."); @@ -62,17 +65,18 @@ public static void main(String... args) { // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); final OAuthRequest request = new OAuthRequest(Verb.GET, - PROTECTED_RESOURCE_URL + "?site=" + site + "&key=" + key, service); + PROTECTED_RESOURCE_URL + "?site=" + site + "&key=" + key); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV1StagingExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV1StagingExample.java new file mode 100644 index 000000000..057f9b27c --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV1StagingExample.java @@ -0,0 +1,97 @@ +package com.github.scribejava.apis.examples; + +import com.github.scribejava.apis.TheThingsNetworkV1StagingApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; + +import java.io.IOException; +import java.net.URLDecoder; +import java.util.Random; +import java.util.Scanner; +import java.util.concurrent.ExecutionException; + +public final class TheThingsNetworkV1StagingExample { + + private static final String NETWORK_NAME = "TTNv1staging"; + private static final String PROTECTED_RESOURCE_URL = "https://account.thethingsnetwork.org/applications"; + + private TheThingsNetworkV1StagingExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + // Replace these with your client id and secret + final String clientId = "your_client_id"; + final String clientSecret = "your_client_secret"; + final String secretState = "secret" + new Random().nextInt(999_999); + final String redirectURI = "https://your_redirect_uri"; + + final OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .state(secretState) + .callback(redirectURI) + .build(TheThingsNetworkV1StagingApi.instance()); + final Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + final String authorizationUrl = service.getAuthorizationUrl(); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + + // TTN v1staging does not have URL safe keys, so we have to decode it + final String code = URLDecoder.decode(in.nextLine(), "UTF-8"); + System.out.println("Using code: "+code); + System.out.println(); + + System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'."); + System.out.print(">>"); + final String value = in.nextLine(); + if (secretState.equals(value)) { + System.out.println("State value does match!"); + } else { + System.out.println("Oops, state value does not match!"); + System.out.println("Expected = " + secretState); + System.out.println("Got = " + value); + System.out.println(); + } + + // Trade the Request Token and Verifier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + final OAuth2AccessToken accessToken = service.getAccessToken(code); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + + service.signRequest(accessToken, request); + request.addHeader("Accept", "application/json"); + final Response response = service.execute(request); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + + if (response.getCode() == 401) { + System.out.println("Not authorised: "+response.getBody()); + } else { + System.out.println("You should see a JSON array of your registered applications:"); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("That's it man! Go and build something awesome with ScribeJava! :)"); + } + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV2PreviewExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV2PreviewExample.java new file mode 100644 index 000000000..acb791c1c --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV2PreviewExample.java @@ -0,0 +1,94 @@ +package com.github.scribejava.apis.examples; + +import com.github.scribejava.apis.TheThingsNetworkV2PreviewApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; + +import java.io.IOException; +import java.util.Random; +import java.util.Scanner; +import java.util.concurrent.ExecutionException; + +public final class TheThingsNetworkV2PreviewExample { + + private static final String NETWORK_NAME = "TTNv2preview"; + private static final String PROTECTED_RESOURCE_URL = + "https://preview.account.thethingsnetwork.org/api/v2/applications"; + + private TheThingsNetworkV2PreviewExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + // Replace these with your client id and secret + final String clientId = "your_client_id"; + final String clientSecret = "your_client_secret"; + final String secretState = "secret" + new Random().nextInt(999_999); + final String redirectURI = "https://your_redirect_uri"; + + final OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .state(secretState) + .callback(redirectURI) + .build(TheThingsNetworkV2PreviewApi.instance()); + final Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + final String authorizationUrl = service.getAuthorizationUrl(); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code = in.nextLine(); + System.out.println(); + + System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'."); + System.out.print(">>"); + final String value = in.nextLine(); + if (secretState.equals(value)) { + System.out.println("State value does match!"); + } else { + System.out.println("Oops, state value does not match!"); + System.out.println("Expected = " + secretState); + System.out.println("Got = " + value); + System.out.println(); + } + + // Trade the Request Token and Verifier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + final OAuth2AccessToken accessToken = service.getAccessToken(code); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + + service.signRequest(accessToken, request); + request.addHeader("Accept", "application/json"); + final Response response = service.execute(request); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + + if (response.getCode() == 401) { + System.out.println("Not authorised: "+response.getBody()); + } else { + System.out.println("You should see a JSON array of your registered applications:"); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("That's it man! Go and build something awesome with ScribeJava! :)"); + } + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TrelloExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TrelloExample.java index c2076371f..dea9fc659 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TrelloExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TrelloExample.java @@ -8,18 +8,21 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class TrelloExample { +public final class TrelloExample { private static final String API_KEY = "your_api_key"; private static final String API_SECRET = "your_api_secret"; private static final String PROTECTED_RESOURCE_URL = "https://trello.com/1/members/me"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey(API_KEY) + private TrelloExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder(API_KEY) .apiSecret(API_SECRET) .build(TrelloApi.instance()); final Scanner in = new Scanner(System.in); @@ -37,21 +40,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TumblrExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TumblrExample.java index 2b1b32f9d..ec21d3bfb 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TumblrExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TumblrExample.java @@ -8,16 +8,19 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class TumblrExample { +public final class TumblrExample { private static final String PROTECTED_RESOURCE_URL = "http://api.tumblr.com/v2/user/info"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("MY_CONSUMER_KEY") + private TumblrExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("MY_CONSUMER_KEY") .apiSecret("MY_CONSUMER_SECRET") // OOB forbidden. We need an url and the better is on the tumblr website ! .callback("http://www.tumblr.com/connect/login_success.html") @@ -37,21 +40,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TutByExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TutByExample.java index c3c7075a2..daa5f0122 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TutByExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TutByExample.java @@ -3,29 +3,30 @@ import java.util.Scanner; import com.github.scribejava.core.builder.ServiceBuilder; -import com.github.scribejava.core.model.OAuthConstants; import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.apis.TutByApi; import com.github.scribejava.core.model.OAuth2AccessToken; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class TutByExample { +public final class TutByExample { private static final String NETWORK_NAME = "Tut.by"; private static final String PROTECTED_RESOURCE_URL = "http://profile.tut.by/getInfo"; - public static void main(String... args) { + private TutByExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId) + final OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) - .grantType(OAuthConstants.AUTHORIZATION_CODE) .callback("http://www.example.com/oauth_callback/") .build(TutByApi.instance()); final Scanner in = new Scanner(System.in, "UTF-8"); @@ -40,21 +41,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TwitterExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TwitterExample.java index 1c26e836b..620eb7820 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TwitterExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TwitterExample.java @@ -8,16 +8,19 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class TwitterExample { +public final class TwitterExample { private static final String PROTECTED_RESOURCE_URL = "https://api.twitter.com/1.1/account/verify_credentials.json"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("your client id") + private TwitterExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("your client id") .apiSecret("your client secret") .build(TwitterApi.instance()); final Scanner in = new Scanner(System.in); @@ -35,21 +38,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if you're curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ViadeoExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ViadeoExample.java index 76516ee91..09dcde65a 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ViadeoExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ViadeoExample.java @@ -7,20 +7,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class ViadeoExample { +public final class ViadeoExample { private static final String NETWORK_NAME = "Viadeo"; private static final String PROTECTED_RESOURCE_URL = "https://api.viadeo.com/me?user_detail=full"; - public static void main(String... args) { + private ViadeoExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your own api key and secret final String apiKey = "your_app_id"; final String apiSecret = "your_api_secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(apiKey) + final OAuth20Service service = new ServiceBuilder(apiKey) .apiSecret(apiSecret) .callback("http://www.example.com/oauth_callback/") .build(ViadeoApi.instance()); @@ -37,21 +40,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExample.java index 5213a1b05..240f78e7c 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExample.java @@ -7,20 +7,23 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth20Service; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class VkontakteExample { +public final class VkontakteExample { private static final String NETWORK_NAME = "Vkontakte.ru"; private static final String PROTECTED_RESOURCE_URL = "https://api.vk.com/method/users.get"; - public static void main(String... args) { + private VkontakteExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { // Replace these with your client id and secret final String clientId = "your client id"; final String clientSecret = "your client secret"; - final OAuth20Service service = new ServiceBuilder() - .apiKey(clientId) + final OAuth20Service service = new ServiceBuilder(clientId) .apiSecret(clientSecret) .scope("wall,offline") // replace with desired scope .callback("http://your.site.com/callback") @@ -38,21 +41,22 @@ public static void main(String... args) { System.out.println(authorizationUrl); System.out.println("And paste the authorization code here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String code = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth2AccessToken accessToken = service.getAccessToken(verifier); + final OAuth2AccessToken accessToken = service.getAccessToken(code); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExternalHttpExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExternalHttpExample.java new file mode 100644 index 000000000..d16b714d8 --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExternalHttpExample.java @@ -0,0 +1,86 @@ +package com.github.scribejava.apis.examples; + +import java.util.Scanner; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.apis.VkontakteApi; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import com.github.scribejava.httpclient.ahc.AhcHttpClient; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import org.asynchttpclient.DefaultAsyncHttpClient; +import org.asynchttpclient.DefaultAsyncHttpClientConfig; + +public final class VkontakteExternalHttpExample { + + private static final String NETWORK_NAME = "Vkontakte.ru"; + private static final String PROTECTED_RESOURCE_URL = "https://api.vk.com/method/users.get"; + + private VkontakteExternalHttpExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + // Replace these with your client id and secret + final String clientId = "your client id"; + final String clientSecret = "your client secret"; + + //create any http client externally + final DefaultAsyncHttpClientConfig httpClientConfig = new DefaultAsyncHttpClientConfig.Builder() + .setMaxConnections(5) + .setRequestTimeout(10_000) + .setPooledConnectionIdleTimeout(1_000) + .setReadTimeout(1_000) + .build(); + //wrap it + try (DefaultAsyncHttpClient ahcHttpClient = new DefaultAsyncHttpClient(httpClientConfig)) { + //wrap it + final AhcHttpClient wrappedAHCHttpClient = new AhcHttpClient(ahcHttpClient); + + final OAuth20Service service = new ServiceBuilder(clientId) + .httpClient(wrappedAHCHttpClient) + .apiSecret(clientSecret) + .scope("wall,offline") // replace with desired scope + .callback("http://your.site.com/callback") + .build(VkontakteApi.instance()); + final Scanner in = new Scanner(System.in); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ==="); + System.out.println(); + + // Obtain the Authorization URL + System.out.println("Fetching the Authorization URL..."); + final String authorizationUrl = service.getAuthorizationUrl(); + System.out.println("Got the Authorization URL!"); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code = in.nextLine(); + System.out.println(); + + // Trade the Request Token and Verfier for the Access Token + System.out.println("Trading the Request Token for an Access Token..."); + final OAuth2AccessToken accessToken = service.getAccessToken(code); + System.out.println("Got the Access Token!"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); + System.out.println(); + + // Now let's go and ask for a protected resource! + System.out.println("Now we're going to access a protected resource..."); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); + service.signRequest(accessToken, request); + final Response response = service.execute(request); + System.out.println("Got it! Lets see what we found..."); + System.out.println(); + System.out.println(response.getCode()); + System.out.println(response.getBody()); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); + } + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/XingExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/XingExample.java index 5542c34cc..9929c6152 100755 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/XingExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/XingExample.java @@ -8,16 +8,19 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class XingExample { +public final class XingExample { private static final String PROTECTED_RESOURCE_URL = "https://api.xing.com/v1/users/me"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("your client id") + private XingExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("your client id") .apiSecret("your client secret") .build(XingApi.instance()); final Scanner in = new Scanner(System.in); @@ -35,21 +38,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getBody()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/YahooExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/YahooExample.java index e2cda508c..581600a3b 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/YahooExample.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/YahooExample.java @@ -8,17 +8,20 @@ import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.model.Verifier; import com.github.scribejava.core.oauth.OAuth10aService; +import java.io.IOException; +import java.util.concurrent.ExecutionException; -public abstract class YahooExample { +public final class YahooExample { private static final String PROTECTED_RESOURCE_URL = "http://social.yahooapis.com/v1/user/A6ROU63MXWDCW3Y5MGCYWVHDJI/profile/status?format=json"; - public static void main(String... args) { - final OAuth10aService service = new ServiceBuilder() - .apiKey("your client id") + private YahooExample() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + final OAuth10aService service = new ServiceBuilder("your client id") .apiSecret("your client secret") .build(YahooApi.instance()); final Scanner in = new Scanner(System.in); @@ -36,21 +39,22 @@ public static void main(String... args) { System.out.println(service.getAuthorizationUrl(requestToken)); System.out.println("And paste the verifier here"); System.out.print(">>"); - final Verifier verifier = new Verifier(in.nextLine()); + final String oauthVerifier = in.nextLine(); System.out.println(); // Trade the Request Token and Verfier for the Access Token System.out.println("Trading the Request Token for an Access Token..."); - final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, verifier); + final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier); System.out.println("Got the Access Token!"); - System.out.println("(if your curious it looks like this: " + accessToken + " )"); + System.out.println("(if your curious it looks like this: " + accessToken + + ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); System.out.println(); // Now let's go and ask for a protected resource! System.out.println("Now we're going to access a protected resource..."); - final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service); + final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); service.signRequest(accessToken, request); - final Response response = request.send(); + final Response response = service.execute(request); System.out.println("Got it! Lets see what we found..."); System.out.println(); System.out.println(response.getCode()); diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/service/OdnoklassnikiServiceTest.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/service/OdnoklassnikiServiceTest.java new file mode 100644 index 000000000..0dded23fb --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/service/OdnoklassnikiServiceTest.java @@ -0,0 +1,42 @@ +package com.github.scribejava.apis.service; + +import com.github.scribejava.apis.OdnoklassnikiApi; +import com.github.scribejava.core.builder.ServiceBuilder; + +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.ParameterList; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.model.Parameter; +import com.github.scribejava.core.oauth.OAuth20Service; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class OdnoklassnikiServiceTest { + + private static final String URL = "https://api.ok.ru/fb.do?method=friends.get&fields=uid%2C" + + "first_name%2Clast_name%2Cpic_2&application_key=AAAAAAAAAAAAAAAA&format=json"; + + private final OAuth20Service service = new ServiceBuilder("0000000000") + .apiSecret("CCCCCCCCCCCCCCCCCCCCCCCC") + .scope("VALUABLE_ACCESS") + .callback("http://your.site.com/callback") + .build(OdnoklassnikiApi.instance()); + + @Test + public void testSigGeneration() { + final OAuth2AccessToken accessToken = new OAuth2AccessToken("d3iwa.403gvrs194740652m1k4w2a503k3c"); + final OAuthRequest request = new OAuthRequest(Verb.GET, URL); + service.signRequest(accessToken, request); + assertEquals("96127f5ca29a8351399e94bbd284ab16", findParam(request.getQueryStringParams(), "sig")); + } + + private static String findParam(ParameterList list, String key) { + for (Parameter param : list.getParams()) { + if (param.getKey().equals(key)) { + return param.getValue(); + } + } + return null; + } +} diff --git a/scribejava-core/pom.xml b/scribejava-core/pom.xml index 08aa2ce57..f41d33f58 100644 --- a/scribejava-core/pom.xml +++ b/scribejava-core/pom.xml @@ -5,7 +5,7 @@ com.github.scribejava scribejava - 2.2.3-SNAPSHOT + 4.1.2-SNAPSHOT ../pom.xml @@ -14,4 +14,16 @@ 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/builder/AbstractServiceBuilder.java b/scribejava-core/src/main/java/com/github/scribejava/core/builder/AbstractServiceBuilder.java deleted file mode 100644 index 41468d1c1..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/builder/AbstractServiceBuilder.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.github.scribejava.core.builder; - -import com.github.scribejava.core.builder.api.DefaultApi10a; -import com.github.scribejava.core.builder.api.DefaultApi20; -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.OAuth10aService; -import com.github.scribejava.core.oauth.OAuth20Service; -import com.github.scribejava.core.utils.Preconditions; - -abstract class AbstractServiceBuilder> { - - private String callback; - private String apiKey; - private String apiSecret; - private String scope; - private String state; - private SignatureType signatureType; - private OutputStream debugStream; - private String grantType; - - AbstractServiceBuilder() { - this.callback = OAuthConstants.OUT_OF_BAND; - this.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 - */ - @SuppressWarnings("unchecked") - public T callback(String callback) { - Preconditions.checkNotNull(callback, "Callback can't be null"); - this.callback = callback; - return (T) this; - } - - /** - * Configures the api key - * - * @param apiKey The api key for your application - * @return the {@link ServiceBuilder} instance for method chaining - */ - @SuppressWarnings("unchecked") - public T apiKey(String apiKey) { - Preconditions.checkEmptyString(apiKey, "Invalid Api key"); - this.apiKey = apiKey; - return (T) this; - } - - /** - * Configures the api secret - * - * @param apiSecret The api secret for your application - * @return the {@link ServiceBuilder} instance for method chaining - */ - @SuppressWarnings("unchecked") - public T apiSecret(String apiSecret) { - Preconditions.checkEmptyString(apiSecret, "Invalid Api secret"); - this.apiSecret = apiSecret; - return (T) 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 - */ - @SuppressWarnings("unchecked") - public T scope(String scope) { - Preconditions.checkEmptyString(scope, "Invalid OAuth scope"); - this.scope = scope; - return (T) 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 - */ - @SuppressWarnings("unchecked") - public T state(String state) { - Preconditions.checkEmptyString(state, "Invalid OAuth state"); - this.state = state; - return (T) this; - } - - /** - * Configures the signature type, choose between header, querystring, etc. Defaults to Header - * - * @param type SignatureType - * @return the {@link ServiceBuilder} instance for method chaining - */ - @SuppressWarnings("unchecked") - public T signatureType(SignatureType type) { - Preconditions.checkNotNull(type, "Signature type can't be null"); - this.signatureType = type; - return (T) this; - } - - @SuppressWarnings("unchecked") - public T debugStream(OutputStream stream) { - Preconditions.checkNotNull(stream, "debug stream can't be null"); - this.debugStream = stream; - return (T) this; - } - - @SuppressWarnings("unchecked") - public T grantType(String grantType) { - Preconditions.checkEmptyString(grantType, "Invalid OAuth grantType"); - this.grantType = grantType; - return (T) this; - } - - @SuppressWarnings("unchecked") - public T debug() { - debugStream(System.out); - return (T) this; - } - - public void checkPreconditions() { - Preconditions.checkEmptyString(apiKey, "You must provide an api key"); - Preconditions.checkEmptyString(apiSecret, "You must provide an api secret"); - } - - public String getCallback() { - return callback; - } - - public String getApiKey() { - return apiKey; - } - - public String getApiSecret() { - return apiSecret; - } - - public String getScope() { - return scope; - } - - public String getState() { - return state; - } - - public SignatureType getSignatureType() { - return signatureType; - } - - public OutputStream getDebugStream() { - return debugStream; - } - - public String getGrantType() { - return grantType; - } - - protected abstract OAuthConfig createConfig(); - - /** - * Returns the fully configured {@link OAuth10aService} - * - * @param api will build Service for this API - * @return fully configured {@link OAuth10aService} - */ - public OAuth10aService build(DefaultApi10a api) { - return api.createService(createConfig()); - } - - /** - * Returns the fully configured {@link OAuth20Service} - * - * @param api will build Service for this API - * @return fully configured {@link OAuth20Service} - */ - public OAuth20Service build(DefaultApi20 api) { - return api.createService(createConfig()); - } -} 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 02f7f3902..6ae14b1c9 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,35 +1,163 @@ package com.github.scribejava.core.builder; +import com.github.scribejava.core.builder.api.BaseApi; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.HttpClientConfig; import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthConstants; import com.github.scribejava.core.oauth.OAuthService; import com.github.scribejava.core.utils.Preconditions; +import java.io.OutputStream; + /** * Implementation of the Builder pattern, with a fluent interface that creates a {@link OAuthService} */ -public class ServiceBuilder extends AbstractServiceBuilder { +public class ServiceBuilder { + + private String callback = OAuthConstants.OUT_OF_BAND; + private String apiKey; + private String apiSecret; + private String scope; + private String state; + private OutputStream debugStream; + private String responseType = "code"; + private String userAgent; + + private HttpClientConfig httpClientConfig; + private HttpClient httpClient; + + /** + * + * @deprecated use {@link #ServiceBuilder(java.lang.String) } + */ + @Deprecated + public ServiceBuilder() { + } + + public ServiceBuilder(String apiKey) { + apiKey(apiKey); + } + + /** + * 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; + } - private Integer connectTimeout; - private Integer readTimeout; + /** + * Configures the api key + * + * @param apiKey The api key for your application + * @return the {@link ServiceBuilder} instance for method chaining + */ + public final 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; + } - public ServiceBuilder connectTimeout(Integer connectTimeout) { - Preconditions.checkNotNull(connectTimeout, "Connection timeout can't be null"); - this.connectTimeout = connectTimeout; + /** + * 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; } - public ServiceBuilder readTimeout(Integer readTimeout) { - Preconditions.checkNotNull(readTimeout, "Read timeout can't be null"); - this.readTimeout = readTimeout; + public ServiceBuilder debugStream(OutputStream debugStream) { + Preconditions.checkNotNull(debugStream, "debug stream can't be null"); + this.debugStream = debugStream; return this; } - @Override - protected OAuthConfig createConfig() { - super.checkPreconditions(); - final OAuthConfig config = new OAuthConfig(getApiKey(), getApiSecret(), getCallback(), getSignatureType(), - getScope(), getDebugStream(), connectTimeout, readTimeout, getGrantType()); - config.setState(getState()); - return config; + public ServiceBuilder responseType(String responseType) { + Preconditions.checkEmptyString(responseType, "Invalid OAuth responseType"); + this.responseType = responseType; + return this; + } + + public ServiceBuilder httpClientConfig(HttpClientConfig httpClientConfig) { + Preconditions.checkNotNull(httpClientConfig, "httpClientConfig can't be null"); + this.httpClientConfig = httpClientConfig; + return this; + } + + /** + * takes precedence over httpClientConfig + * + * @param httpClient externally created HTTP client + * @return the {@link ServiceBuilder} instance for method chaining + */ + public ServiceBuilder httpClient(HttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + public ServiceBuilder userAgent(String userAgent) { + this.userAgent = userAgent; + return this; + } + + public ServiceBuilder debug() { + debugStream(System.out); + return this; + } + + /** + * + * @deprecated apiKey will be required param for the ServiceBuilder constructor + * {@link #ServiceBuilder(java.lang.String) } + */ + @Deprecated + public void checkPreconditions() { + Preconditions.checkEmptyString(apiKey, "You must provide an api key"); + } + + /** + * 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) { + checkPreconditions(); + return api.createService(new OAuthConfig(apiKey, apiSecret, callback, scope, debugStream, state, responseType, + userAgent, httpClientConfig, httpClient)); } } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/builder/ServiceBuilderAsync.java b/scribejava-core/src/main/java/com/github/scribejava/core/builder/ServiceBuilderAsync.java deleted file mode 100644 index 6f5a218cb..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/builder/ServiceBuilderAsync.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.github.scribejava.core.builder; - -import com.ning.http.client.AsyncHttpClientConfig; -import com.github.scribejava.core.model.OAuthConfigAsync; -import com.github.scribejava.core.utils.Preconditions; - -public class ServiceBuilderAsync extends AbstractServiceBuilder { - - private AsyncHttpClientConfig asyncHttpClientConfig; - private String asyncHttpProviderClassName; - - public ServiceBuilderAsync asyncHttpClientConfig(AsyncHttpClientConfig asyncHttpClientConfig) { - Preconditions.checkNotNull(asyncHttpClientConfig, "asyncHttpClientConfig can't be null"); - this.asyncHttpClientConfig = asyncHttpClientConfig; - return this; - } - - @Override - public void checkPreconditions() { - super.checkPreconditions(); - Preconditions.checkNotNull(asyncHttpClientConfig, "You must provide an asyncHttpClientConfig"); - } - - @Override - protected OAuthConfigAsync createConfig() { - checkPreconditions(); - final OAuthConfigAsync configAsync = new OAuthConfigAsync(getApiKey(), getApiSecret(), getCallback(), - getSignatureType(), getScope(), getGrantType(), getDebugStream(), asyncHttpClientConfig); - configAsync.setState(getState()); - configAsync.setAsyncHttpProviderClassName(asyncHttpProviderClassName); - return configAsync; - } - - public ServiceBuilderAsync asyncHttpProviderClassName(String asyncHttpProviderClassName) { - this.asyncHttpProviderClassName = asyncHttpProviderClassName; - return this; - } -} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/BaseApi.java b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/BaseApi.java new file mode 100644 index 000000000..7f6fbdd4f --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/BaseApi.java @@ -0,0 +1,9 @@ +package com.github.scribejava.core.builder.api; + +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.oauth.OAuthService; + +public interface BaseApi> { + + T createService(OAuthConfig config); +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/DefaultApi10a.java b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/DefaultApi10a.java index 89d1eb499..b7167a86e 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/DefaultApi10a.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/DefaultApi10a.java @@ -30,7 +30,7 @@ * fine-tune the process. Please read the javadocs of the interfaces to get an idea of what to do. * */ -public abstract class DefaultApi10a { +public abstract class DefaultApi10a implements BaseApi { /** * Returns the access token extractor. @@ -77,6 +77,13 @@ public SignatureService getSignatureService() { return new HMACSha1SignatureService(); } + /** + * @return the signature type, choose between header, querystring, etc. Defaults to Header + */ + public OAuth1SignatureType getSignatureType() { + return OAuth1SignatureType.Header; + } + /** * Returns the timestamp service. * @@ -126,7 +133,18 @@ public Verb getRequestTokenVerb() { */ public abstract String getAuthorizationUrl(OAuth1RequestToken requestToken); + @Override public OAuth10aService createService(OAuthConfig config) { return new OAuth10aService(this, config); } + + /** + * http://tools.ietf.org/html/rfc5849 says that "The client MAY omit the empty "oauth_token" protocol parameter from + * the request", but not all oauth servers are good boys. + * + * @return whether to inlcude empty oauth_token param to the request + */ + public boolean isEmptyOAuthTokenParamIsRequired() { + return false; + } } 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 c789da72a..5a9e7ce44 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,26 +1,29 @@ package com.github.scribejava.core.builder.api; -import com.github.scribejava.core.extractors.OAuth2AccessTokenExtractor; +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 (draft 11) + * 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 (draft 11) protocol correctly, you just need to extend this class and define the - * getters for your endpoints. + * 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 + * 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 { +public abstract class DefaultApi20 implements BaseApi { /** * Returns the access token extractor. @@ -28,16 +31,16 @@ public abstract class DefaultApi20 { * @return access token extractor */ public TokenExtractor getAccessTokenExtractor() { - return OAuth2AccessTokenExtractor.instance(); + return OAuth2AccessTokenJsonExtractor.instance(); } /** - * Returns the verb for the access token endpoint (defaults to GET) + * Returns the verb for the access token endpoint (defaults to POST) * * @return access token endpoint verb */ public Verb getAccessTokenVerb() { - return Verb.GET; + return Verb.POST; } /** @@ -47,15 +50,48 @@ public Verb getAccessTokenVerb() { */ 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 abstract String getAuthorizationUrl(OAuthConfig config); + 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); } + + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_AUTHORIZATION_REQUEST_HEADER_FIELD; + } } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/OAuth1SignatureType.java b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/OAuth1SignatureType.java new file mode 100644 index 000000000..7660b5826 --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/OAuth1SignatureType.java @@ -0,0 +1,7 @@ +package com.github.scribejava.core.builder.api; + +public enum OAuth1SignatureType { + + Header, + QueryString +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/OAuth2SignatureType.java b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/OAuth2SignatureType.java new file mode 100644 index 000000000..a6825a757 --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/builder/api/OAuth2SignatureType.java @@ -0,0 +1,30 @@ +package com.github.scribejava.core.builder.api; + +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.OAuthRequest; + +public enum OAuth2SignatureType { + /** + * https://tools.ietf.org/html/rfc6750#section-2.1 + */ + BEARER_AUTHORIZATION_REQUEST_HEADER_FIELD { + @Override + public void signRequest(OAuth2AccessToken accessToken, OAuthRequest request) { + request.addHeader("Authorization", "Bearer " + accessToken.getAccessToken()); + } + + }, + /** + * https://tools.ietf.org/html/rfc6750#section-2.3 + */ + BEARER_URI_QUERY_PARAMETER { + @Override + public void signRequest(OAuth2AccessToken accessToken, OAuthRequest request) { + request.addQuerystringParameter(OAuthConstants.ACCESS_TOKEN, accessToken.getAccessToken()); + } + + }; + + public abstract void signRequest(OAuth2AccessToken accessToken, OAuthRequest request); +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/exceptions/OAuthConnectionException.java b/scribejava-core/src/main/java/com/github/scribejava/core/exceptions/OAuthConnectionException.java deleted file mode 100644 index 93feb8c42..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/exceptions/OAuthConnectionException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.github.scribejava.core.exceptions; - -public class OAuthConnectionException extends OAuthException { - - private static final long serialVersionUID = 6901269342236961310L; - private static final String MSG = "There was a problem while creating a connection to the remote service: "; - - public OAuthConnectionException(String url, Exception e) { - super(MSG + url, e); - } -} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/exceptions/OAuthParametersMissingException.java b/scribejava-core/src/main/java/com/github/scribejava/core/exceptions/OAuthParametersMissingException.java index ddf77ab78..2d4a5dfc4 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/exceptions/OAuthParametersMissingException.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/exceptions/OAuthParametersMissingException.java @@ -1,6 +1,6 @@ package com.github.scribejava.core.exceptions; -import com.github.scribejava.core.model.AbstractRequest; +import com.github.scribejava.core.model.OAuthRequest; /** * Specialized exception that represents a missing OAuth parameter. @@ -16,7 +16,7 @@ public class OAuthParametersMissingException extends OAuthException { * * @param request OAuthRequest that caused the error */ - public OAuthParametersMissingException(AbstractRequest request) { + public OAuthParametersMissingException(OAuthRequest request) { super(String.format(MSG, request)); } } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/AbstractOAuth1TokenExtractor.java b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/AbstractOAuth1TokenExtractor.java index 4d968d83c..61578d01b 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/AbstractOAuth1TokenExtractor.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/AbstractOAuth1TokenExtractor.java @@ -1,9 +1,11 @@ package com.github.scribejava.core.extractors; +import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.github.scribejava.core.exceptions.OAuthException; import com.github.scribejava.core.model.OAuth1Token; +import com.github.scribejava.core.model.Response; import com.github.scribejava.core.utils.OAuthEncoder; import com.github.scribejava.core.utils.Preconditions; @@ -16,19 +18,20 @@ */ public abstract class AbstractOAuth1TokenExtractor implements TokenExtractor { - private static final String OAUTH_TOKEN_REGEXP = "oauth_token=([^&]+)"; - private static final String OAUTH_TOKEN_SECRET_REGEXP = "oauth_token_secret=([^&]*)"; + private static final Pattern OAUTH_TOKEN_REGEXP_PATTERN = Pattern.compile("oauth_token=([^&]+)"); + private static final Pattern OAUTH_TOKEN_SECRET_REGEXP_PATTERN = Pattern.compile("oauth_token_secret=([^&]*)"); /** * {@inheritDoc} */ @Override - public T extract(String response) { - Preconditions.checkEmptyString(response, + public T extract(Response response) throws IOException { + final String body = response.getBody(); + Preconditions.checkEmptyString(body, "Response body is incorrect. Can't extract a token from an empty string"); - final String token = extract(response, Pattern.compile(OAUTH_TOKEN_REGEXP)); - final String secret = extract(response, Pattern.compile(OAUTH_TOKEN_SECRET_REGEXP)); - return createToken(token, secret, response); + final String token = extract(body, OAUTH_TOKEN_REGEXP_PATTERN); + final String secret = extract(body, OAUTH_TOKEN_SECRET_REGEXP_PATTERN); + return createToken(token, secret, body); } private String extract(String response, Pattern p) { diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/BaseStringExtractor.java b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/BaseStringExtractor.java index 113dc3515..21cb3431b 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/BaseStringExtractor.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/BaseStringExtractor.java @@ -1,19 +1,19 @@ package com.github.scribejava.core.extractors; -import com.github.scribejava.core.model.AbstractRequest; +import com.github.scribejava.core.model.OAuthRequest; /** - * Simple command object that extracts a base string from a {@link AbstractRequest} + * Simple command object that extracts a base string from a {@link OAuthRequest} */ public interface BaseStringExtractor { /** - * Extracts an url-encoded base string from the {@link AbstractRequest}. + * Extracts an url-encoded base string from the {@link OAuthRequest}. * * See the oauth spec for more info on this. * * @param request the OAuthRequest * @return the url-encoded base string */ - String extract(AbstractRequest request); + String extract(OAuthRequest request); } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/BaseStringExtractorImpl.java b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/BaseStringExtractorImpl.java index e2ba3b950..879dac9ae 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/BaseStringExtractorImpl.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/BaseStringExtractorImpl.java @@ -1,7 +1,7 @@ package com.github.scribejava.core.extractors; import com.github.scribejava.core.exceptions.OAuthParametersMissingException; -import com.github.scribejava.core.model.AbstractRequest; +import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.ParameterList; import com.github.scribejava.core.utils.OAuthEncoder; import com.github.scribejava.core.utils.Preconditions; @@ -17,7 +17,7 @@ public class BaseStringExtractorImpl implements BaseStringExtractor { * {@inheritDoc} */ @Override - public String extract(AbstractRequest request) { + public String extract(OAuthRequest request) { checkPreconditions(request); final String verb = OAuthEncoder.encode(getVerb(request)); final String url = OAuthEncoder.encode(getUrl(request)); @@ -25,15 +25,15 @@ public String extract(AbstractRequest request) { return String.format(AMPERSAND_SEPARATED_STRING, verb, url, params); } - protected String getVerb(AbstractRequest request) { + protected String getVerb(OAuthRequest request) { return request.getVerb().name(); } - protected String getUrl(AbstractRequest request) { + protected String getUrl(OAuthRequest request) { return request.getSanitizedUrl(); } - protected String getSortedAndEncodedParams(AbstractRequest request) { + protected String getSortedAndEncodedParams(OAuthRequest request) { final ParameterList params = new ParameterList(); params.addAll(request.getQueryStringParams()); params.addAll(request.getBodyParams()); @@ -41,7 +41,7 @@ protected String getSortedAndEncodedParams(AbstractRequest request) { return params.sort().asOauthBaseString(); } - protected void checkPreconditions(AbstractRequest request) { + protected void checkPreconditions(OAuthRequest request) { Preconditions.checkNotNull(request, "Cannot extract base string from a null object"); if (request.getOauthParameters() == null || request.getOauthParameters().size() <= 0) { diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/HeaderExtractor.java b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/HeaderExtractor.java index d84390a91..e6e6156e4 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/HeaderExtractor.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/HeaderExtractor.java @@ -1,6 +1,6 @@ package com.github.scribejava.core.extractors; -import com.github.scribejava.core.model.AbstractRequest; +import com.github.scribejava.core.model.OAuthRequest; /** * Simple command object that generates an OAuth Authorization header to include in the request. @@ -13,5 +13,5 @@ public interface HeaderExtractor { * @param request the AbstractRequest to inspect and generate the header * @return the Http header value */ - String extract(AbstractRequest request); + String extract(OAuthRequest request); } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/HeaderExtractorImpl.java b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/HeaderExtractorImpl.java index a3c142a10..2a840521c 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/HeaderExtractorImpl.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/HeaderExtractorImpl.java @@ -3,7 +3,7 @@ import java.util.Map; import com.github.scribejava.core.exceptions.OAuthParametersMissingException; import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.AbstractRequest; +import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.utils.OAuthEncoder; import com.github.scribejava.core.utils.Preconditions; @@ -20,7 +20,7 @@ public class HeaderExtractorImpl implements HeaderExtractor { * {@inheritDoc} */ @Override - public String extract(AbstractRequest request) { + public String extract(OAuthRequest request) { checkPreconditions(request); final Map parameters = request.getOauthParameters(); final StringBuilder header = new StringBuilder(parameters.size() * ESTIMATED_PARAM_LENGTH); @@ -40,7 +40,7 @@ public String extract(AbstractRequest request) { return header.toString(); } - private void checkPreconditions(AbstractRequest request) { + private void checkPreconditions(OAuthRequest request) { Preconditions.checkNotNull(request, "Cannot extract a header from a null object"); if (request.getOauthParameters() == null || request.getOauthParameters().size() <= 0) { diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/OAuth2AccessTokenExtractor.java b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/OAuth2AccessTokenExtractor.java index 928f9f4d8..8af44d3aa 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/OAuth2AccessTokenExtractor.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/OAuth2AccessTokenExtractor.java @@ -1,18 +1,24 @@ package com.github.scribejava.core.extractors; +import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.github.scribejava.core.exceptions.OAuthException; import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.Response; import com.github.scribejava.core.utils.OAuthEncoder; import com.github.scribejava.core.utils.Preconditions; /** - * Default implementation of {@link TokenExtractor} for OAuth 2.0 + * Custom implementation of {@link TokenExtractor} for OAuth 2.0 */ public class OAuth2AccessTokenExtractor implements TokenExtractor { - private static final String TOKEN_REGEX = "access_token=([^&]+)"; + private static final Pattern ACCESS_TOKEN_REGEX_PATTERN = Pattern.compile("access_token=([^&]+)"); + private static final Pattern TOKEN_TYPE_REGEX_PATTERN = Pattern.compile("token_type=([^&]+)"); + private static final Pattern EXPIRES_IN_REGEX_PATTERN = Pattern.compile("expires_in=([^&]+)"); + private static final Pattern REFRESH_TOKEN_REGEX_PATTERN = Pattern.compile("refresh_token=([^&]+)"); + private static final Pattern SCOPE_REGEX_PATTERN = Pattern.compile("scope=([^&]+)"); protected OAuth2AccessTokenExtractor() { } @@ -30,17 +36,37 @@ public static OAuth2AccessTokenExtractor instance() { * {@inheritDoc} */ @Override - public OAuth2AccessToken extract(String response) { - Preconditions.checkEmptyString(response, + public OAuth2AccessToken extract(Response response) throws IOException { + final String body = response.getBody(); + Preconditions.checkEmptyString(body, "Response body is incorrect. Can't extract a token from an empty string"); - final Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response); + final String accessToken = extractParameter(body, ACCESS_TOKEN_REGEX_PATTERN, true); + final String tokenType = extractParameter(body, TOKEN_TYPE_REGEX_PATTERN, false); + final String expiresInString = extractParameter(body, EXPIRES_IN_REGEX_PATTERN, false); + Integer expiresIn; + try { + expiresIn = expiresInString == null ? null : Integer.valueOf(expiresInString); + } catch (NumberFormatException nfe) { + expiresIn = null; + } + final String refreshToken = extractParameter(body, REFRESH_TOKEN_REGEX_PATTERN, false); + final String scope = extractParameter(body, SCOPE_REGEX_PATTERN, false); + + return new OAuth2AccessToken(accessToken, tokenType, expiresIn, refreshToken, scope, body); + } + + private static String extractParameter(String response, Pattern regexPattern, boolean required) + throws OAuthException { + + final Matcher matcher = regexPattern.matcher(response); if (matcher.find()) { - final String token = OAuthEncoder.decode(matcher.group(1)); - return new OAuth2AccessToken(token, response); + return OAuthEncoder.decode(matcher.group(1)); + } else if (required) { + throw new OAuthException("Response body is incorrect. Can't extract a '" + regexPattern.pattern() + + "' from this: '" + response + "'", null); } else { - throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", - null); + return null; } } } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/OAuth2AccessTokenJsonExtractor.java b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/OAuth2AccessTokenJsonExtractor.java index a06e8054d..0c24755b3 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/OAuth2AccessTokenJsonExtractor.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/OAuth2AccessTokenJsonExtractor.java @@ -1,14 +1,29 @@ package com.github.scribejava.core.extractors; +import java.io.IOException; +import java.net.URI; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.github.scribejava.core.exceptions.OAuthException; import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuth2AccessTokenErrorResponse; +import com.github.scribejava.core.model.Response; import com.github.scribejava.core.utils.Preconditions; +/** + * JSON (default) implementation of {@link TokenExtractor} for OAuth 2.0 + */ public class OAuth2AccessTokenJsonExtractor implements TokenExtractor { - private static final String ACCESS_TOKENS_REGEXP = "\"access_token\"\\s*:\\s*\"(\\S*?)\""; + private static final Pattern ACCESS_TOKEN_REGEX_PATTERN = Pattern.compile("\"access_token\"\\s*:\\s*\"(\\S*?)\""); + private static final Pattern TOKEN_TYPE_REGEX_PATTERN = Pattern.compile("\"token_type\"\\s*:\\s*\"(\\S*?)\""); + private static final Pattern EXPIRES_IN_REGEX_PATTERN = Pattern.compile("\"expires_in\"\\s*:\\s*\"?(\\d*?)\"?\\D"); + private static final Pattern REFRESH_TOKEN_REGEX_PATTERN = Pattern.compile("\"refresh_token\"\\s*:\\s*\"(\\S*?)\""); + private static final Pattern SCOPE_REGEX_PATTERN = Pattern.compile("\"scope\"\\s*:\\s*\"(\\S*?)\""); + private static final Pattern ERROR_REGEX_PATTERN = Pattern.compile("\"error\"\\s*:\\s*\"(\\S*?)\""); + private static final Pattern ERROR_DESCRIPTION_REGEX_PATTERN + = Pattern.compile("\"error_description\"\\s*:\\s*\"([^\"]*?)\""); + private static final Pattern ERROR_URI_REGEX_PATTERN = Pattern.compile("\"error_uri\"\\s*:\\s*\"(\\S*?)\""); protected OAuth2AccessTokenJsonExtractor() { } @@ -23,17 +38,70 @@ public static OAuth2AccessTokenJsonExtractor instance() { } @Override - public OAuth2AccessToken extract(String response) { - return new OAuth2AccessToken(extractAccessToken(response), response); + public OAuth2AccessToken extract(Response response) throws IOException { + final String body = response.getBody(); + Preconditions.checkEmptyString(body, + "Response body is incorrect. Can't extract a token from an empty string"); + + if (response.getCode() != 200) { + generateError(response.getBody()); + } + return createToken(body); + } + + /** + * Related documentation: https://tools.ietf.org/html/rfc6749#section-5.2 + * + * @param response response + */ + protected void generateError(String response) { + final String errorInString = extractParameter(response, ERROR_REGEX_PATTERN, true); + final String errorDescription = extractParameter(response, ERROR_DESCRIPTION_REGEX_PATTERN, false); + final String errorUriInString = extractParameter(response, ERROR_URI_REGEX_PATTERN, false); + URI errorUri; + try { + errorUri = errorUriInString == null ? null : URI.create(errorUriInString); + } catch (IllegalArgumentException iae) { + errorUri = null; + } + + throw new OAuth2AccessTokenErrorResponse(OAuth2AccessTokenErrorResponse.ErrorCode.valueOf(errorInString), + errorDescription, errorUri, response); } - protected String extractAccessToken(String response) { - Preconditions.checkEmptyString(response, "Cannot extract a token from a null or empty String"); - final Matcher matcher = Pattern.compile(ACCESS_TOKENS_REGEXP).matcher(response); + private OAuth2AccessToken createToken(String response) { + final String accessToken = extractParameter(response, ACCESS_TOKEN_REGEX_PATTERN, true); + final String tokenType = extractParameter(response, TOKEN_TYPE_REGEX_PATTERN, false); + final String expiresInString = extractParameter(response, EXPIRES_IN_REGEX_PATTERN, false); + Integer expiresIn; + try { + expiresIn = expiresInString == null ? null : Integer.valueOf(expiresInString); + } catch (NumberFormatException nfe) { + expiresIn = null; + } + final String refreshToken = extractParameter(response, REFRESH_TOKEN_REGEX_PATTERN, false); + final String scope = extractParameter(response, SCOPE_REGEX_PATTERN, false); + + return createToken(accessToken, tokenType, expiresIn, refreshToken, scope, response); + } + + protected OAuth2AccessToken createToken(String accessToken, String tokenType, Integer expiresIn, + String refreshToken, String scope, String response) { + return new OAuth2AccessToken(accessToken, tokenType, expiresIn, refreshToken, scope, response); + } + + protected static String extractParameter(String response, Pattern regexPattern, boolean required) + throws OAuthException { + final Matcher matcher = regexPattern.matcher(response); if (matcher.find()) { return matcher.group(1); - } else { - throw new OAuthException("Cannot extract an access token. Response was: " + response); } + + if (required) { + throw new OAuthException("Response body is incorrect. Can't extract a '" + regexPattern.pattern() + + "' from this: '" + response + "'", null); + } + + return null; } } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/TokenExtractor.java b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/TokenExtractor.java index eec9546cc..00c662d81 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/extractors/TokenExtractor.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/extractors/TokenExtractor.java @@ -1,7 +1,11 @@ package com.github.scribejava.core.extractors; +import com.github.scribejava.core.exceptions.OAuthException; +import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Token; +import java.io.IOException; + /** * Simple command object that extracts a concrete {@link Token} from a String * @param concrete type of Token @@ -11,8 +15,9 @@ public interface TokenExtractor { /** * Extracts the concrete type of token from the contents of an Http Response * - * @param response the contents of the response + * @param response the whole response * @return OAuth access token + * @throws java.io.IOException in case of troubles while getting body from the response */ - T extract(String response); + T extract(Response response) throws IOException, OAuthException; } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/AbstractAsyncOnlyHttpClient.java b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/AbstractAsyncOnlyHttpClient.java new file mode 100644 index 000000000..091a95849 --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/AbstractAsyncOnlyHttpClient.java @@ -0,0 +1,33 @@ +package com.github.scribejava.core.httpclient; + +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +public abstract class AbstractAsyncOnlyHttpClient implements HttpClient { + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents) throws InterruptedException, ExecutionException, IOException { + return executeAsync(userAgent, headers, httpVerb, completeUrl, bodyContents, null, + (OAuthRequest.ResponseConverter) null).get(); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents) throws InterruptedException, ExecutionException, IOException { + return executeAsync(userAgent, headers, httpVerb, completeUrl, bodyContents, null, + (OAuthRequest.ResponseConverter) null).get(); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents) throws InterruptedException, ExecutionException, IOException { + return executeAsync(userAgent, headers, httpVerb, completeUrl, bodyContents, null, + (OAuthRequest.ResponseConverter) null).get(); + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/HttpClient.java b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/HttpClient.java new file mode 100644 index 000000000..5793faf5c --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/HttpClient.java @@ -0,0 +1,37 @@ +package com.github.scribejava.core.httpclient; + +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public interface HttpClient { + String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded"; + String CONTENT_TYPE = "Content-Type"; + String CONTENT_LENGTH = "Content-Length"; + + void close() throws IOException; + + Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter); + + Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter); + + Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter); + + Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents) throws InterruptedException, ExecutionException, IOException; + + Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents) throws InterruptedException, ExecutionException, IOException; + + Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents) throws InterruptedException, ExecutionException, IOException; +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/HttpClientConfig.java b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/HttpClientConfig.java new file mode 100644 index 000000000..3c28d6249 --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/HttpClientConfig.java @@ -0,0 +1,6 @@ +package com.github.scribejava.core.httpclient; + +public interface HttpClientConfig { + + HttpClientConfig createDefaultConfig(); +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/HttpClientProvider.java b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/HttpClientProvider.java new file mode 100644 index 000000000..5b69156d2 --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/HttpClientProvider.java @@ -0,0 +1,6 @@ +package com.github.scribejava.core.httpclient; + +public interface HttpClientProvider { + + HttpClient createClient(HttpClientConfig httpClientConfig); +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpClient.java b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpClient.java new file mode 100644 index 000000000..761f8be2a --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpClient.java @@ -0,0 +1,165 @@ +package com.github.scribejava.core.httpclient.jdk; + +import com.github.scribejava.core.exceptions.OAuthException; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import java.io.File; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class JDKHttpClient implements HttpClient { + + private final JDKHttpClientConfig config; + + public JDKHttpClient(JDKHttpClientConfig clientConfig) { + config = clientConfig; + } + + @Override + public void close() throws IOException { + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + try { + final T response = converter.convert(execute(userAgent, headers, httpVerb, completeUrl, bodyContents)); + callback.onCompleted(response); + return new JDKHttpFuture<>(response); + } catch (InterruptedException | ExecutionException | IOException e) { + callback.onThrowable(e); + return new JDKHttpFuture<>(e); + } + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + try { + final T response = converter.convert(execute(userAgent, headers, httpVerb, completeUrl, bodyContents)); + if (callback != null) { + callback.onCompleted(response); + } + return new JDKHttpFuture<>(response); + } catch (InterruptedException | ExecutionException | IOException e) { + if (callback != null) { + callback.onThrowable(e); + } + return new JDKHttpFuture<>(e); + } + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + throw new UnsupportedOperationException("JDKHttpClient do not support File payload for the moment"); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents) throws InterruptedException, ExecutionException, IOException { + return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.BYTE_ARRAY, bodyContents); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents) throws InterruptedException, ExecutionException, IOException { + return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.STRING, bodyContents); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents) throws InterruptedException, ExecutionException, IOException { + throw new UnsupportedOperationException("JDKHttpClient do not support File payload for the moment"); + } + + private Response doExecute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + BodyType bodyType, Object bodyContents) throws IOException { + final HttpURLConnection connection = (HttpURLConnection) new URL(completeUrl).openConnection(); + connection.setInstanceFollowRedirects(config.isFollowRedirects()); + connection.setRequestMethod(httpVerb.name()); + if (config.getConnectTimeout() != null) { + connection.setConnectTimeout(config.getConnectTimeout()); + } + if (config.getReadTimeout() != null) { + connection.setReadTimeout(config.getReadTimeout()); + } + addHeaders(connection, headers, userAgent); + if (httpVerb.isPermitBody()) { + bodyType.setBody(connection, bodyContents); + } + + try { + connection.connect(); + final int responseCode = connection.getResponseCode(); + return new Response(responseCode, connection.getResponseMessage(), parseHeaders(connection), + responseCode >= 200 && responseCode < 400 ? connection.getInputStream() + : connection.getErrorStream()); + } catch (UnknownHostException e) { + throw new OAuthException("The IP address of a host could not be determined.", e); + } + } + + private enum BodyType { + BYTE_ARRAY { + @Override + void setBody(HttpURLConnection connection, Object bodyContents) throws IOException { + addBody(connection, (byte[]) bodyContents); + } + }, + STRING { + @Override + void setBody(HttpURLConnection connection, Object bodyContents) throws IOException { + addBody(connection, ((String) bodyContents).getBytes()); + } + }; + + abstract void setBody(HttpURLConnection connection, Object bodyContents) throws IOException; + } + + private static Map parseHeaders(HttpURLConnection conn) { + final Map headers = new HashMap<>(); + for (Map.Entry> entry : conn.getHeaderFields().entrySet()) { + final String key = entry.getKey(); + if ("Content-Encoding".equalsIgnoreCase(key)) { + headers.put("Content-Encoding", entry.getValue().get(0)); + } else { + headers.put(key, entry.getValue().get(0)); + } + } + return headers; + } + + private static void addHeaders(HttpURLConnection connection, Map headers, String userAgent) { + for (Map.Entry entry : headers.entrySet()) { + connection.setRequestProperty(entry.getKey(), entry.getValue()); + } + if (userAgent != null) { + connection.setRequestProperty(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent); + } + } + + private static void addBody(HttpURLConnection connection, byte[] content) throws IOException { + final int contentLength = content.length; + connection.setRequestProperty(CONTENT_LENGTH, String.valueOf(contentLength)); + + if (connection.getRequestProperty(CONTENT_TYPE) == null) { + connection.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); + } + if (contentLength > 0) { + connection.setDoOutput(true); + connection.getOutputStream().write(content); + } + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpClientConfig.java b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpClientConfig.java new file mode 100644 index 000000000..cfb97b359 --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpClientConfig.java @@ -0,0 +1,52 @@ +package com.github.scribejava.core.httpclient.jdk; + +import com.github.scribejava.core.httpclient.HttpClientConfig; + +public class JDKHttpClientConfig implements HttpClientConfig { + + private Integer connectTimeout; + private Integer readTimeout; + private boolean followRedirects = true; + + @Override + public JDKHttpClientConfig createDefaultConfig() { + return defaultConfig(); + } + + public static JDKHttpClientConfig defaultConfig() { + return new JDKHttpClientConfig(); + } + + public Integer getConnectTimeout() { + return connectTimeout; + } + + public void setConnectTimeout(Integer connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public Integer getReadTimeout() { + return readTimeout; + } + + public void setReadTimeout(Integer readTimeout) { + this.readTimeout = readTimeout; + } + + public boolean isFollowRedirects() { + return followRedirects; + } + + /** + * 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; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpFuture.java b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpFuture.java new file mode 100644 index 000000000..1922d3aef --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpFuture.java @@ -0,0 +1,58 @@ +package com.github.scribejava.core.httpclient.jdk; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Fake Future. Just to have Future API for the default JDK Http client. It's NOT Async in any way. Just facade.
+ * That's it. Sync execution with Async methods. This class does NOT provide any async executions. + */ +public class JDKHttpFuture implements Future { + + private final Exception exception; + private final V response; + + public JDKHttpFuture(Exception exception) { + this(null, exception); + } + + public JDKHttpFuture(V response) { + this(response, null); + } + + private JDKHttpFuture(V response, Exception exception) { + this.response = response; + this.exception = exception; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return true; + } + + @Override + public V get() throws InterruptedException, ExecutionException { + if (exception != null) { + throw new ExecutionException(exception); + } + + return response; + } + + @Override + public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return get(); + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpProvider.java b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpProvider.java new file mode 100644 index 000000000..04472e78a --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/httpclient/jdk/JDKHttpProvider.java @@ -0,0 +1,16 @@ +package com.github.scribejava.core.httpclient.jdk; + +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.HttpClientConfig; +import com.github.scribejava.core.httpclient.HttpClientProvider; + +public class JDKHttpProvider implements HttpClientProvider { + + @Override + public HttpClient createClient(HttpClientConfig config) { + if (config instanceof JDKHttpClientConfig) { + return new JDKHttpClient((JDKHttpClientConfig) config); + } + return null; + } +} 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 deleted file mode 100644 index c48f83c74..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/AbstractRequest.java +++ /dev/null @@ -1,294 +0,0 @@ -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"; - protected static final String CONTENT_LENGTH = "Content-Length"; - protected static final String CONTENT_TYPE = "Content-Type"; - 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/ForceTypeOfHttpRequest.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/ForceTypeOfHttpRequest.java deleted file mode 100644 index b0387a535..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/ForceTypeOfHttpRequest.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.scribejava.core.model; - -public enum ForceTypeOfHttpRequest { - - NONE, - FORCE_ASYNC_ONLY_HTTP_REQUESTS, - FORCE_SYNC_ONLY_HTTP_REQUESTS, - PREFER_ASYNC_ONLY_HTTP_REQUESTS, - PREFER_SYNC_ONLY_HTTP_REQUESTS -} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1AccessToken.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1AccessToken.java index 838fc2adb..e57a7db39 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1AccessToken.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1AccessToken.java @@ -3,11 +3,11 @@ import java.util.Objects; /** - * Represents an OAuth 1 Access Token http://oauth.net/core/1.0a/#rfc.section.6.3.2 + * Represents an OAuth 1 Access Token http://tools.ietf.org/html/rfc5849#section-2.3 */ public class OAuth1AccessToken extends OAuth1Token { - private static final long serialVersionUID = -8784937061938486135L; + private static final long serialVersionUID = -103999293167210966L; public OAuth1AccessToken(String token, String tokenSecret) { this(token, tokenSecret, null); @@ -17,6 +17,26 @@ public OAuth1AccessToken(String token, String tokenSecret, String rawResponse) { super(token, tokenSecret, rawResponse); } + /** + * The token identifier. + * + * @return oauth_token + */ + @Override + public String getToken() { + return super.getToken(); + } + + /** + * The token shared-secret. + * + * @return oauth_token_secret + */ + @Override + public String getTokenSecret() { + return super.getTokenSecret(); + } + @Override public int hashCode() { int hash = 3; diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1RequestToken.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1RequestToken.java index b7db7047b..1c53d4932 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1RequestToken.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1RequestToken.java @@ -3,17 +3,17 @@ import java.util.Objects; /** - * Represents an OAuth 1 Request Token http://oauth.net/core/1.0a/#rfc.section.6.1.2 + * Represents an OAuth 1 Request Token http://tools.ietf.org/html/rfc5849#section-2.1 */ public class OAuth1RequestToken extends OAuth1Token { - private static final long serialVersionUID = 359527630020350893L; + private static final long serialVersionUID = 6185104114662587991L; /** * oauth_callback_confirmed: *

- * MUST be present and set to true. The Consumer MAY use this to confirm that the Service Provider received the - * callback value.

+ * MUST be present and set to "true". The parameter is used to differentiate from previous versions of the protocol. + *

*/ private final boolean oauthCallbackConfirmed; @@ -30,6 +30,26 @@ public OAuth1RequestToken(String token, String tokenSecret, boolean oauthCallbac this.oauthCallbackConfirmed = oauthCallbackConfirmed; } + /** + * The temporary credentials identifier. + * + * @return oauth_token + */ + @Override + public String getToken() { + return super.getToken(); + } + + /** + * The temporary credentials shared-secret. + * + * @return oauth_token_secret + */ + @Override + public String getTokenSecret() { + return super.getTokenSecret(); + } + public boolean isOauthCallbackConfirmed() { return oauthCallbackConfirmed; } @@ -69,6 +89,6 @@ public String toString() { return "OAuth1RequestToken{" + "oauth_token=" + getToken() + ", oauth_token_secret=" + getTokenSecret() - + ", oauthCallbackConfirmed=" + oauthCallbackConfirmed + '}'; + + ", oauth_callback_confirmed=" + oauthCallbackConfirmed + '}'; } } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1Token.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1Token.java index c50fbd29e..3d02f49aa 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1Token.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth1Token.java @@ -9,18 +9,8 @@ public abstract class OAuth1Token extends Token { private static final long serialVersionUID = 6285873427974823019L; - /** - * oauth_token: - *

- * The Request/Access Token.

- */ private final String token; - /** - * oauth_token_secret: - *

- * The Token Secret.

- */ private final String tokenSecret; public OAuth1Token(String token, String tokenSecret, String rawResponse) { diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2AccessToken.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2AccessToken.java index 5205aa64f..b97e4e0a0 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2AccessToken.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2AccessToken.java @@ -4,7 +4,11 @@ import java.util.Objects; /** - * Represents an OAuth 2 Access Token http://tools.ietf.org/html/rfc6749#section-5.1 + * Represents an OAuth 2 Access token. + *

+ * http://tools.ietf.org/html/rfc6749#section-5.1 + * + * @see OAuth 2 Access Token Specification

*/ public class OAuth2AccessToken extends Token { diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2AccessTokenErrorResponse.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2AccessTokenErrorResponse.java new file mode 100644 index 000000000..eba31404e --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2AccessTokenErrorResponse.java @@ -0,0 +1,50 @@ +package com.github.scribejava.core.model; + +import com.github.scribejava.core.exceptions.OAuthException; + +import java.net.URI; + +/** + * Representing "5.2. Error Response" + */ +public class OAuth2AccessTokenErrorResponse extends OAuthException { + + private static final long serialVersionUID = 2309424849700276816L; + + public enum ErrorCode { + invalid_request, invalid_client, invalid_grant, unauthorized_client, unsupported_grant_type, invalid_scope + } + + private final ErrorCode errorCode; + private final String errorDescription; + private final URI errorUri; + private final String rawResponse; + + public OAuth2AccessTokenErrorResponse(ErrorCode errorCode, String errorDescription, URI errorUri, + String rawResponse) { + super(rawResponse); + if (errorCode == null) { + throw new IllegalArgumentException("errorCode must not be null"); + } + this.errorCode = errorCode; + this.errorDescription = errorDescription; + this.errorUri = errorUri; + this.rawResponse = rawResponse; + } + + public ErrorCode getErrorCode() { + return errorCode; + } + + public String getErrorDescription() { + return errorDescription; + } + + public URI getErrorUri() { + return errorUri; + } + + public String getRawResponse() { + return rawResponse; + } +} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2Authorization.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2Authorization.java new file mode 100644 index 000000000..8c99f395b --- /dev/null +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuth2Authorization.java @@ -0,0 +1,43 @@ +package com.github.scribejava.core.model; + +/** + * represents Authorization Response http://tools.ietf.org/html/rfc6749#section-4.1.2 + * + * If the resource owner grants the access request, the authorization server issues an authorization code and delivers + * it to the client by adding the following parameters to the query component of the redirection URI using the + * "application/x-www-form-urlencoded" format. + * + */ +public class OAuth2Authorization { + + /** + * REQUIRED. The authorization code generated by the authorization server. The authorization code MUST expire + * shortly after it is issued to mitigate the risk of leaks. A maximum authorization code lifetime of 10 minutes is + * RECOMMENDED. The client MUST NOT use the authorization code more than once. If an authorization code is used more + * than once, the authorization server MUST deny the request and SHOULD revoke (when possible) all tokens previously + * issued based on that authorization code. The authorization code is bound to the client identifier and redirection + * URI. + */ + private String code; + /** + * REQUIRED if the "state" parameter was present in the client authorization request. The exact value received from + * the client. + */ + private String state; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } +} 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 92b8bbbbc..244ca6731 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,5 +1,7 @@ package com.github.scribejava.core.model; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.HttpClientConfig; import java.io.IOException; import java.io.OutputStream; @@ -11,29 +13,32 @@ 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 String grantType; private final OutputStream debugStream; - private final Integer connectTimeout; - private final Integer readTimeout; - private String state; + private final String state; + private final String responseType; + private final String userAgent; + + private HttpClientConfig httpClientConfig; + private HttpClient httpClient; public OAuthConfig(String key, String secret) { - this(key, secret, null, null, null, null, null, null, null); + this(key, secret, null, null, null, null, null, null, null, null); } - public OAuthConfig(String key, String secret, String callback, SignatureType type, String scope, - OutputStream stream, Integer connectTimeout, Integer readTimeout, String grantType) { - this.apiKey = key; - this.apiSecret = secret; + public OAuthConfig(String apiKey, String apiSecret, String callback, String scope, OutputStream debugStream, + String state, String responseType, String userAgent, HttpClientConfig httpClientConfig, + HttpClient httpClient) { + this.apiKey = apiKey; + this.apiSecret = apiSecret; this.callback = callback; - this.signatureType = type; this.scope = scope; - this.debugStream = stream; - this.connectTimeout = connectTimeout; - this.readTimeout = readTimeout; - this.grantType = grantType; + this.debugStream = debugStream; + this.state = state; + this.responseType = responseType; + this.userAgent = userAgent; + this.httpClientConfig = httpClientConfig; + this.httpClient = httpClient; } public String getApiKey() { @@ -48,32 +53,20 @@ public String getCallback() { return callback; } - public SignatureType getSignatureType() { - return signatureType; - } - public String getScope() { return scope; } - public boolean hasScope() { - return scope != null; - } - - public String getGrantType() { - return grantType; - } - - public boolean hasGrantType() { - return grantType != null; + public String getState() { + return state; } - public Integer getConnectTimeout() { - return connectTimeout; + public String getResponseType() { + return responseType; } - public Integer getReadTimeout() { - return readTimeout; + public String getUserAgent() { + return userAgent; } public void log(String message) { @@ -87,17 +80,11 @@ public void log(String message) { } } - /** - * Sets optional value used by some provider implementations that is exchanged with provider to avoid CSRF attacks. - * - * @param state some secret key that client side shall never receive - */ - public void setState(String state) { - this.state = state; + public HttpClientConfig getHttpClientConfig() { + return httpClientConfig; } - public String getState() { - return state; + public HttpClient getHttpClient() { + return httpClient; } - } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConfigAsync.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConfigAsync.java deleted file mode 100644 index 1387a9b01..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthConfigAsync.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.github.scribejava.core.model; - -import com.ning.http.client.AsyncHttpClientConfig; -import java.io.OutputStream; - -public class OAuthConfigAsync extends OAuthConfig { - - private AsyncHttpClientConfig asyncHttpClientConfig; - private String asyncHttpProviderClassName; - - public OAuthConfigAsync(String key, String secret) { - super(key, secret); - } - - public OAuthConfigAsync(String key, String secret, String callback, SignatureType type, String scope, - String grantType, OutputStream stream, AsyncHttpClientConfig asyncHttpClientConfig) { - super(key, secret, callback, type, scope, stream, null, null, grantType); - this.asyncHttpClientConfig = asyncHttpClientConfig; - } - - public AsyncHttpClientConfig getAsyncHttpClientConfig() { - return asyncHttpClientConfig; - } - - public void setAsyncHttpProviderClassName(String asyncHttpProviderClassName) { - this.asyncHttpProviderClassName = asyncHttpProviderClassName; - } - - public String getAsyncHttpProviderClassName() { - return asyncHttpProviderClassName; - } -} 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 229392c38..2cf8d236a 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 @@ -20,8 +20,8 @@ public interface OAuthConstants { String OUT_OF_BAND = "oob"; String VERIFIER = "oauth_verifier"; String HEADER = "Authorization"; - OAuth1RequestToken EMPTY_TOKEN = new OAuth1RequestToken("", ""); String SCOPE = "scope"; + String BASIC = "Basic"; // OAuth 2.0 String ACCESS_TOKEN = "access_token"; @@ -29,7 +29,16 @@ public interface OAuthConstants { 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 66a36415a..3f50440eb 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,88 +1,275 @@ package com.github.scribejava.core.model; +import com.github.scribejava.core.exceptions.OAuthException; +import java.io.File; import java.io.IOException; -import java.net.HttpURLConnection; +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.OAuthConnectionException; -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.oauth.OAuthService; -public class OAuthRequest extends AbstractRequest { +/** + * The representation of an OAuth HttpRequest. + */ +public class OAuthRequest { - private HttpURLConnection connection; + private static final String OAUTH_PREFIX = "oauth_"; - public OAuthRequest(Verb verb, String url, OAuthService service) { - super(verb, url, service); - } + 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 String charset; + + private String stringPayload; + private byte[] byteArrayPayload; + private File filePayload; + + private final Map oauthParameters = new HashMap<>(); + + private String realm; /** - * Execute the request and return a {@link Response} + * Default constructor. * - * @return Http Response + * @param verb Http verb/method + * @param url resource URL + */ + public OAuthRequest(Verb verb, String url) { + this.verb = verb; + this.url = url; + } + + /** + * Adds an OAuth parameter. * - * @throws RuntimeException if the connection cannot be created. + * @param key name of the parameter + * @param value value of the parameter + * @throws IllegalArgumentException if the parameter is not an OAuth parameter */ - public Response send() { - final ForceTypeOfHttpRequest forceTypeOfHttpRequest = ScribeJavaConfig.getForceTypeOfHttpRequests(); + public void addOAuthParameter(String key, String value) { + oauthParameters.put(checkKey(key), value); + } - if (ForceTypeOfHttpRequest.FORCE_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - throw new OAuthException("Cannot use sync operations, only async"); + 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)); } - if (ForceTypeOfHttpRequest.PREFER_ASYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - getService().getConfig().log("Cannot use sync operations, only async"); + } + + 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 (verb.isPermitBody()) { + bodyParams.add(key, value); + } else { + querystringParams.add(key, value); } + } + + /** + * Set 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 setPayload(String payload) { + resetPayload(); + stringPayload = payload; + } + + /** + * Overloaded version for byte arrays + * + * @param payload byte[] + */ + public void setPayload(byte[] payload) { + resetPayload(); + byteArrayPayload = payload.clone(); + } + + /** + * Overloaded version for File + * + * @param payload File + */ + public void setPayload(File payload) { + resetPayload(); + filePayload = payload; + } + + private void resetPayload() { + stringPayload = null; + byteArrayPayload = null; + filePayload = null; + } + + /** + * 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 { - createConnection(); - return doSend(); - } catch (IOException | RuntimeException e) { - throw new OAuthConnectionException(getCompleteUrl(), e); + 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); } } - 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()); + /** + * 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("\\?.*", ""); } - if (config.getReadTimeout() != null) { - connection.setReadTimeout(config.getReadTimeout()); + } + + /** + * Returns the body of the request (set in {@link #setPayload(java.lang.String)}) + * + * @return form encoded string + */ + public String getStringPayload() { + return stringPayload; + } + + /** + * @return the body of the request (set in {@link #setPayload(byte[])} or in + * {@link #addBodyParameter(java.lang.String, java.lang.String)} ) + */ + public byte[] getByteArrayPayload() { + if (byteArrayPayload != null) { + return byteArrayPayload; } - addHeaders(); - if (hasBodyContent()) { - addBody(getByteBodyContents()); + final String body = bodyParams.asFormUrlEncodedString(); + try { + return body.getBytes(getCharset()); + } catch (UnsupportedEncodingException uee) { + throw new OAuthException("Unsupported Charset: " + getCharset(), uee); } - 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()); - } + public File getFilePayload() { + return filePayload; } - void addHeaders() { - for (Map.Entry entry : getHeaders().entrySet()) { - connection.setRequestProperty(entry.getKey(), entry.getValue()); - } + @Override + public String toString() { + return String.format("@Request(%s %s)", getVerb(), getUrl()); } - void addBody(byte[] content) throws IOException { - connection.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.length)); + public Verb getVerb() { + return verb; + } - if (connection.getRequestProperty(CONTENT_TYPE) == null) { - connection.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); - } - connection.setDoOutput(true); - connection.getOutputStream().write(content); + 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; } - void setConnection(HttpURLConnection connection) { - this.connection = connection; + public interface ResponseConverter { + + T convert(Response response) throws IOException; } + } 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 deleted file mode 100644 index a7dd1dce5..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/OAuthRequestAsync.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.github.scribejava.core.model; - -import com.ning.http.client.AsyncCompletionHandler; -import com.ning.http.client.AsyncHttpClient; -import com.ning.http.client.FluentCaseInsensitiveStringsMap; -import com.ning.http.client.ProxyServer; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Future; -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.oauth.OAuthService; - -public class OAuthRequestAsync extends AbstractRequest { - - public static final ResponseConverter RESPONSE_CONVERTER = new ResponseConverter() { - @Override - public Response convert(com.ning.http.client.Response response) throws IOException { - final FluentCaseInsensitiveStringsMap map = response.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()); - } - return new Response(response.getStatusCode(), response.getStatusText(), headersMap, - response.getResponseBody(), response.getResponseBodyAsStream()); - } - }; - - public OAuthRequestAsync(Verb verb, String url, OAuthService service) { - super(verb, url, service); - } - - public Future sendAsync(OAuthAsyncRequestCallback callback, ResponseConverter converter) { - return sendAsync(callback, converter, null); - } - - public Future sendAsync(OAuthAsyncRequestCallback callback, ResponseConverter converter, - ProxyServer proxyServer) { - 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(); - if (ForceTypeOfHttpRequest.PREFER_SYNC_ONLY_HTTP_REQUESTS == forceTypeOfHttpRequest) { - service.getConfig().log("Cannot use async operations, only sync"); - } - final String completeUrl = getCompleteUrl(); - final AsyncHttpClient.BoundRequestBuilder boundRequestBuilder; - switch (getVerb()) { - case GET: - boundRequestBuilder = service.getAsyncHttpClient().prepareGet(completeUrl); - break; - case POST: - boundRequestBuilder = service.getAsyncHttpClient().preparePost(completeUrl).setBody(getBodyContents()); - break; - default: - throw new IllegalArgumentException("message build error: unknown verb type"); - } - if (proxyServer != null) { - boundRequestBuilder.setProxyServer(proxyServer); - } - return boundRequestBuilder.execute(new OAuthAsyncCompletionHandler<>(callback, converter)); - } - - private static class OAuthAsyncCompletionHandler extends AsyncCompletionHandler { - - private final OAuthAsyncRequestCallback callback; - private final ResponseConverter converter; - - OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback callback, ResponseConverter converter) { - this.callback = callback; - this.converter = converter; - } - - @Override - public T onCompleted(com.ning.http.client.Response response) throws IOException { - final T t = converter.convert(response); - if (callback != null) { - callback.onCompleted(t); - } - return t; - } - - @Override - public void onThrowable(Throwable t) { - if (callback != null) { - callback.onThrowable(t); - } - } - }; - - public Future sendAsync(OAuthAsyncRequestCallback callback) { - return sendAsync(callback, RESPONSE_CONVERTER, null); - } - - public Future sendAsync(OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - return sendAsync(callback, RESPONSE_CONVERTER, proxyServer); - } - - public interface ResponseConverter { - - T convert(com.ning.http.client.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 c04bca9cd..39d806652 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 @@ -26,8 +26,10 @@ public ParameterList() { public ParameterList(Map map) { this(); - for (Map.Entry entry : map.entrySet()) { - params.add(new Parameter(entry.getKey(), entry.getValue())); + if (map != null && !map.isEmpty()) { + for (Map.Entry entry : map.entrySet()) { + params.add(new Parameter(entry.getKey(), entry.getValue())); + } } } @@ -41,9 +43,9 @@ public String appendTo(String url) { if (queryString.equals(EMPTY_STRING)) { return url; } else { - url += url.indexOf(QUERY_STRING_SEPARATOR) == -1 ? QUERY_STRING_SEPARATOR : PARAM_SEPARATOR; - url += queryString; - return url; + return url + + (url.indexOf(QUERY_STRING_SEPARATOR) == -1 ? QUERY_STRING_SEPARATOR : PARAM_SEPARATOR) + + queryString; } } @@ -58,9 +60,9 @@ public String asFormUrlEncodedString() { final StringBuilder builder = new StringBuilder(); for (Parameter p : params) { - builder.append('&').append(p.asUrlEncodedPair()); + builder.append(PARAM_SEPARATOR).append(p.asUrlEncodedPair()); } - return builder.toString().substring(1); + return builder.substring(1); } public void addAll(ParameterList other) { @@ -68,7 +70,7 @@ public void addAll(ParameterList other) { } public void addQuerystring(String queryString) { - if (queryString != null && queryString.length() > 0) { + 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]); 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 bce6e584a..8a4807677 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 @@ -2,68 +2,50 @@ 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 final int code; + private final String message; + private final Map headers; private String body; private InputStream stream; - private Map headers; - public Response(int code, String message, Map headers, String body, InputStream stream) { + private Response(int code, String message, Map headers) { this.code = code; - this.headers = headers; - this.body = body; this.message = message; + this.headers = headers; + } + + public Response(int code, String message, Map headers, InputStream stream) { + this(code, message, headers); 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); - } + public Response(int code, String message, Map headers, String body) { + this(code, message, headers); + this.body = body; } - private String parseBodyContents() { + private String parseBodyContents() throws IOException { + if (stream == null) { + return null; + } if ("gzip".equals(getHeader("Content-Encoding"))) { - body = StreamUtils.getGzipStreamContents(getStream()); + body = StreamUtils.getGzipStreamContents(stream); } else { - body = StreamUtils.getStreamContents(getStream()); + body = StreamUtils.getStreamContents(stream); } 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; + return code >= 200 && code < 400; } - /** - * Obtains the HTTP Response body - * - * @return response body - */ - public String getBody() { + public String getBody() throws IOException { return body == null ? parseBodyContents() : body; } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/ScribeJavaConfig.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/ScribeJavaConfig.java deleted file mode 100644 index 171bbac1a..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/ScribeJavaConfig.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.github.scribejava.core.model; - -public abstract class ScribeJavaConfig { - - private static ForceTypeOfHttpRequest forceTypeOfHttpRequests = ForceTypeOfHttpRequest.NONE; - - public static ForceTypeOfHttpRequest getForceTypeOfHttpRequests() { - return forceTypeOfHttpRequests; - } - - public static void setForceTypeOfHttpRequests(ForceTypeOfHttpRequest forceTypeOfHttpRequests) { - ScribeJavaConfig.forceTypeOfHttpRequests = forceTypeOfHttpRequests; - } -} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/SignatureType.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/SignatureType.java deleted file mode 100644 index 26ffe054e..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/SignatureType.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.github.scribejava.core.model; - -public enum SignatureType { - - Header, - QueryString -} diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/Verb.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/Verb.java index 6ca83a517..ddcebc6b2 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/Verb.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/model/Verb.java @@ -5,5 +5,15 @@ */ public enum Verb { - GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, PATCH + GET(false), POST(true), PUT(true), DELETE(true), HEAD(false), OPTIONS(false), TRACE(false), PATCH(true); + + private final boolean permitBody; + + Verb(boolean permitBody) { + this.permitBody = permitBody; + } + + public boolean isPermitBody() { + return permitBody; + } } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/model/Verifier.java b/scribejava-core/src/main/java/com/github/scribejava/core/model/Verifier.java deleted file mode 100644 index fc8a92195..000000000 --- a/scribejava-core/src/main/java/com/github/scribejava/core/model/Verifier.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.scribejava.core.model; - -import com.github.scribejava.core.utils.Preconditions; - -/** - * Represents an OAuth verifier code. - */ -public class Verifier { - - private final String value; - - /** - * Default constructor. - * - * @param value verifier value - */ - public Verifier(String value) { - Preconditions.checkNotNull(value, "Must provide a valid string as verifier"); - this.value = value; - } - - public String getValue() { - return value; - } -} 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 76b076935..ad9e6eda0 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,28 +1,25 @@ package com.github.scribejava.core.oauth; -import com.ning.http.client.ProxyServer; 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.builder.api.OAuth1SignatureType; import com.github.scribejava.core.model.OAuth1AccessToken; import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.model.OAuth1Token; 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.model.Verifier; import com.github.scribejava.core.services.Base64Encoder; import com.github.scribejava.core.utils.MapUtils; +import java.util.concurrent.ExecutionException; /** * OAuth 1.0a implementation of {@link OAuthService} */ -public class OAuth10aService extends OAuthService { +public class OAuth10aService extends OAuthService { private static final String VERSION = "1.0"; private final DefaultApi10a api; @@ -38,117 +35,129 @@ public OAuth10aService(DefaultApi10a api, OAuthConfig config) { this.api = api; } - /** - * Retrieve the request token. - * - * @return request token - */ - public OAuth1RequestToken getRequestToken() { + public final OAuth1RequestToken getRequestToken() throws IOException, InterruptedException, ExecutionException { final OAuthConfig config = getConfig(); config.log("obtaining request token from " + api.getRequestTokenEndpoint()); - final OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint(), this); - - config.log("setting oauth_callback to " + config.getCallback()); - request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback()); - addOAuthParams(request, OAuthConstants.EMPTY_TOKEN); - appendSignature(request); + final OAuthRequest request = prepareRequestTokenRequest(); config.log("sending request..."); - final Response response = request.send(); + final Response response = execute(request); final String body = response.getBody(); config.log("response status code: " + response.getCode()); config.log("response body: " + body); - return api.getRequestTokenExtractor().extract(body); + return api.getRequestTokenExtractor().extract(response); + } + + public final Future getRequestTokenAsync() { + return getRequestTokenAsync(null); + } + + public final Future getRequestTokenAsync( + OAuthAsyncRequestCallback callback) { + final OAuthConfig config = getConfig(); + config.log("async obtaining request token from " + api.getRequestTokenEndpoint()); + final OAuthRequest request = prepareRequestTokenRequest(); + return execute(request, callback, new OAuthRequest.ResponseConverter() { + @Override + public OAuth1RequestToken convert(Response response) throws IOException { + return getApi().getRequestTokenExtractor().extract(response); + } + }); } - private void addOAuthParams(AbstractRequest request, OAuth1Token token) { + protected OAuthRequest prepareRequestTokenRequest() { + final OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint()); + final OAuthConfig config = getConfig(); + config.log("setting oauth_callback to " + config.getCallback()); + request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback()); + addOAuthParams(request, ""); + appendSignature(request); + return request; + } + + protected void addOAuthParams(OAuthRequest 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()); - if (config.hasScope()) { - request.addOAuthParameter(OAuthConstants.SCOPE, config.getScope()); + final String scope = config.getScope(); + if (scope != null) { + request.addOAuthParameter(OAuthConstants.SCOPE, scope); } - request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, token)); + request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, tokenSecret)); config.log("appended additional OAuth parameters: " + MapUtils.toString(request.getOauthParameters())); } - public final OAuth1AccessToken getAccessToken(OAuth1RequestToken requestToken, Verifier verifier) { - 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, verifier); - final Response response = request.send(); - return api.getAccessTokenExtractor().extract(response.getBody()); + public final OAuth1AccessToken getAccessToken(OAuth1RequestToken requestToken, String oauthVerifier) + throws IOException, InterruptedException, ExecutionException { + getConfig().log("obtaining access token from " + api.getAccessTokenEndpoint()); + final OAuthRequest request = prepareAccessTokenRequest(requestToken, oauthVerifier); + final Response response = execute(request); + return api.getAccessTokenExtractor().extract(response); + } + + public final Future getAccessTokenAsync(OAuth1RequestToken requestToken, String oauthVerifier) { + return getAccessTokenAsync(requestToken, oauthVerifier, null); } /** - * Start the request to retrieve the access token. The optionally provided callback will be called with the Token - * when it is available. + * 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 verifier verifier code + * @param oauthVerifier oauth_verifier * @param callback optional callback * @return Future */ - public final Future getAccessTokenAsync(OAuth1RequestToken requestToken, Verifier verifier, + public final Future getAccessTokenAsync(OAuth1RequestToken requestToken, String oauthVerifier, OAuthAsyncRequestCallback callback) { - return getAccessTokenAsync(requestToken, verifier, callback, null); - } - - public final Future getAccessTokenAsync(OAuth1RequestToken requestToken, Verifier verifier, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { 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, verifier); - return request.sendAsync(callback, new OAuthRequestAsync.ResponseConverter() { + final OAuthRequest request = prepareAccessTokenRequest(requestToken, oauthVerifier); + return execute(request, callback, new OAuthRequest.ResponseConverter() { @Override - public OAuth1AccessToken convert(com.ning.http.client.Response response) throws IOException { - return getApi().getAccessTokenExtractor() - .extract(OAuthRequestAsync.RESPONSE_CONVERTER.convert(response).getBody()); + public OAuth1AccessToken convert(Response response) throws IOException { + return getApi().getAccessTokenExtractor().extract(response); } - }, proxyServer); + }); } - protected void prepareAccessTokenRequest(AbstractRequest request, OAuth1RequestToken requestToken, - Verifier verifier) { + protected OAuthRequest prepareAccessTokenRequest(OAuth1RequestToken requestToken, String oauthVerifier) { + final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); final OAuthConfig config = getConfig(); request.addOAuthParameter(OAuthConstants.TOKEN, requestToken.getToken()); - request.addOAuthParameter(OAuthConstants.VERIFIER, verifier.getValue()); - config.log("setting token to: " + requestToken + " and verifier to: " + verifier); - addOAuthParams(request, requestToken); + request.addOAuthParameter(OAuthConstants.VERIFIER, oauthVerifier); + config.log("setting token to: " + requestToken + " and verifier to: " + oauthVerifier); + addOAuthParams(request, requestToken.getTokenSecret()); appendSignature(request); + return request; } - public void signRequest(OAuth1AccessToken token, AbstractRequest request) { + @Override + public void signRequest(OAuth1AccessToken token, OAuthRequest request) { final OAuthConfig config = getConfig(); config.log("signing request: " + request.getCompleteUrl()); - // Do not append the token if empty. This is for two legged OAuth calls. - if (!token.isEmpty()) { + if (!token.isEmpty() || api.isEmptyOAuthTokenParamIsRequired()) { request.addOAuthParameter(OAuthConstants.TOKEN, token.getToken()); } config.log("setting token to: " + token); - addOAuthParams(request, token); + addOAuthParams(request, token.getTokenSecret()); appendSignature(request); } - /** - * {@inheritDoc} - */ @Override public String getVersion() { return VERSION; } /** - * Returns the URL where you should redirect your users to authenticate your application. + * 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 @@ -157,22 +166,22 @@ public String getAuthorizationUrl(OAuth1RequestToken requestToken) { return api.getAuthorizationUrl(requestToken); } - private String getSignature(AbstractRequest request, OAuth1Token token) { + private String getSignature(OAuthRequest 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(), token.getTokenSecret()); + 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) { + protected void appendSignature(OAuthRequest request) { final OAuthConfig config = getConfig(); - switch (config.getSignatureType()) { + final OAuth1SignatureType signatureType = api.getSignatureType(); + switch (signatureType) { case Header: config.log("using Http Header signature"); @@ -187,7 +196,7 @@ private void appendSignature(AbstractRequest request) { } break; default: - throw new IllegalStateException("Unknown new Signature Type '" + config.getSignatureType() + "'."); + throw new IllegalStateException("Unknown new Signature Type '" + signatureType + "'."); } } 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 84ae8a8ef..4565a4165 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,20 +1,21 @@ package com.github.scribejava.core.oauth; -import com.ning.http.client.ProxyServer; +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 com.github.scribejava.core.model.Verifier; +import java.util.Map; +import java.util.concurrent.ExecutionException; -public class OAuth20Service extends OAuthService { +public class OAuth20Service extends OAuthService { private static final String VERSION = "2.0"; private final DefaultApi20 api; @@ -30,50 +31,155 @@ public OAuth20Service(DefaultApi20 api, OAuthConfig config) { this.api = api; } - public final OAuth2AccessToken getAccessToken(Verifier verifier) { - final Response response = createAccessTokenRequest(verifier, - new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)).send(); - return api.getAccessTokenExtractor().extract(response.getBody()); + //protected to facilitate mocking + protected OAuth2AccessToken sendAccessTokenRequestSync(OAuthRequest request) + throws IOException, InterruptedException, ExecutionException { + return api.getAccessTokenExtractor().extract(execute(request)); + } + + //protected to facilitate mocking + protected Future sendAccessTokenRequestAsync(OAuthRequest request) { + return sendAccessTokenRequestAsync(request, null); + } + + //protected to facilitate mocking + protected Future sendAccessTokenRequestAsync(OAuthRequest request, + OAuthAsyncRequestCallback callback) { + + return execute(request, callback, new OAuthRequest.ResponseConverter() { + @Override + public OAuth2AccessToken convert(Response response) throws IOException { + return getApi().getAccessTokenExtractor().extract(response); + } + }); + } + + public final Future getAccessTokenAsync(String code) { + return getAccessToken(code, null); + } + + public final OAuth2AccessToken getAccessToken(String code) + throws IOException, InterruptedException, ExecutionException { + final OAuthRequest request = createAccessTokenRequest(code); + + 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 verifier verifier code + * @param code code * @param callback optional callback * @return Future */ - public final Future getAccessTokenAsync(Verifier verifier, + public final Future getAccessToken(String code, OAuthAsyncRequestCallback callback) { - return getAccessTokenAsync(verifier, callback, null); - } + final OAuthRequest request = createAccessTokenRequest(code); - public final Future getAccessTokenAsync(Verifier verifier, - OAuthAsyncRequestCallback callback, ProxyServer proxyServer) { - final OAuthRequestAsync request = createAccessTokenRequest(verifier, - new OAuthRequestAsync(api.getAccessTokenVerb(), api.getAccessTokenEndpoint(), this)); - 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); + return sendAccessTokenRequestAsync(request, callback); } - protected T createAccessTokenRequest(Verifier verifier, T request) { + protected OAuthRequest createAccessTokenRequest(String code) { + final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); final OAuthConfig config = getConfig(); request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); - request.addParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret()); - request.addParameter(OAuthConstants.CODE, verifier.getValue()); + final String apiSecret = config.getApiSecret(); + if (apiSecret != null) { + request.addParameter(OAuthConstants.CLIENT_SECRET, apiSecret); + } + request.addParameter(OAuthConstants.CODE, code); request.addParameter(OAuthConstants.REDIRECT_URI, config.getCallback()); - if (config.hasScope()) { - request.addParameter(OAuthConstants.SCOPE, config.getScope()); + 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 Future refreshAccessTokenAsync(String refreshToken) { + return refreshAccessToken(refreshToken, null); + } + + public final OAuth2AccessToken refreshAccessToken(String refreshToken) + throws IOException, InterruptedException, ExecutionException { + final OAuthRequest request = createRefreshTokenRequest(refreshToken); + + return sendAccessTokenRequestSync(request); + } + + public final Future refreshAccessToken(String refreshToken, + OAuthAsyncRequestCallback callback) { + final OAuthRequest request = createRefreshTokenRequest(refreshToken); + + return sendAccessTokenRequestAsync(request, callback); + } + + protected OAuthRequest createRefreshTokenRequest(String refreshToken) { + if (refreshToken == null || refreshToken.isEmpty()) { + throw new IllegalArgumentException("The refreshToken cannot be null or empty"); + } + final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getRefreshTokenEndpoint()); + final OAuthConfig config = getConfig(); + request.addParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); + final String apiSecret = config.getApiSecret(); + if (apiSecret != null) { + request.addParameter(OAuthConstants.CLIENT_SECRET, apiSecret); + } + 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, InterruptedException, ExecutionException { + final OAuthRequest request = createAccessTokenPasswordGrantRequest(uname, password); + + return sendAccessTokenRequestSync(request); + } + + public final Future getAccessTokenPasswordGrantAsync(String uname, String password) { + return getAccessTokenPasswordGrantAsync(uname, password, null); + } + + /** + * 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 OAuthRequest request = createAccessTokenPasswordGrantRequest(uname, password); + + return sendAccessTokenRequestAsync(request, callback); + } + + protected OAuthRequest createAccessTokenPasswordGrantRequest(String username, String password) { + final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); + 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); } - if (config.hasGrantType()) { - request.addParameter(OAuthConstants.GRANT_TYPE, config.getGrantType()); + + 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; } @@ -85,8 +191,9 @@ public String getVersion() { return VERSION; } - public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) { - request.addQuerystringParameter(OAuthConstants.ACCESS_TOKEN, accessToken.getAccessToken()); + @Override + public void signRequest(OAuth2AccessToken accessToken, OAuthRequest request) { + api.getSignatureType().signRequest(accessToken, request); } /** @@ -94,11 +201,44 @@ public void signRequest(OAuth2AccessToken accessToken, AbstractRequest request) * * @return the URL where you should redirect your users */ - public String getAuthorizationUrl() { - return api.getAuthorizationUrl(getConfig()); + 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(); + int end = redirectLocation.indexOf('#'); + if (end == -1) { + end = redirectLocation.length(); + } + for (String param : redirectLocation.substring(redirectLocation.indexOf('?') + 1, end).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 ad7c1d4b4..df58ce3ea 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,54 +1,58 @@ package com.github.scribejava.core.oauth; -import com.ning.http.client.AsyncHttpClient; -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.model.ForceTypeOfHttpRequest; +import com.github.scribejava.core.httpclient.HttpClientProvider; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.HttpClientConfig; +import com.github.scribejava.core.httpclient.jdk.JDKHttpClient; +import com.github.scribejava.core.httpclient.jdk.JDKHttpClientConfig; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; import com.github.scribejava.core.model.OAuthConfig; -import com.github.scribejava.core.model.OAuthConfigAsync; -import com.github.scribejava.core.model.ScribeJavaConfig; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Token; +import java.io.File; + +import java.io.IOException; +import java.util.ServiceLoader; +import java.util.concurrent.ExecutionException; +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. + * @param type of token used to sign the request */ -public abstract class OAuthService { +public abstract class OAuthService implements AutoCloseable { private final OAuthConfig config; - private AsyncHttpClient asyncHttpClient; + private final HttpClient httpClient; public OAuthService(OAuthConfig config) { this.config = config; - final ForceTypeOfHttpRequest forceTypeOfHttpRequest = ScribeJavaConfig.getForceTypeOfHttpRequests(); - if (config instanceof OAuthConfigAsync) { - 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"); - } - final OAuthConfigAsync asyncConfig = (OAuthConfigAsync) config; - final String asyncHttpProviderClassName = asyncConfig.getAsyncHttpProviderClassName(); + final HttpClientConfig httpClientConfig = config.getHttpClientConfig(); + final HttpClient externalHttpClient = config.getHttpClient(); - asyncHttpClient = asyncHttpProviderClassName == null - ? new AsyncHttpClient(asyncConfig.getAsyncHttpClientConfig()) - : new AsyncHttpClient(asyncHttpProviderClassName, asyncConfig.getAsyncHttpClientConfig()); + if (httpClientConfig == null && externalHttpClient == null) { + httpClient = new JDKHttpClient(JDKHttpClientConfig.defaultConfig()); } else { - 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"); - } + httpClient = externalHttpClient == null ? getClient(httpClientConfig) : externalHttpClient; } } - public AsyncHttpClient getAsyncHttpClient() { - return asyncHttpClient; + private static HttpClient getClient(HttpClientConfig config) { + for (HttpClientProvider provider : ServiceLoader.load(HttpClientProvider.class)) { + final HttpClient client = provider.createClient(config); + if (client != null) { + return client; + } + } + return null; } - public void closeAsyncClient() { - asyncHttpClient.close(); + @Override + public void close() throws IOException { + httpClient.close(); } public OAuthConfig getConfig() { @@ -61,4 +65,44 @@ public OAuthConfig getConfig() { * @return OAuth version as string */ public abstract String getVersion(); + + public abstract void signRequest(T token, OAuthRequest request); + + public Future executeAsync(OAuthRequest request) { + return execute(request, null); + } + + public Future execute(OAuthRequest request, OAuthAsyncRequestCallback callback) { + return execute(request, callback, null); + } + + public Future execute(OAuthRequest request, OAuthAsyncRequestCallback callback, + OAuthRequest.ResponseConverter converter) { + + final File filePayload = request.getFilePayload(); + if (filePayload != null) { + return httpClient.executeAsync(config.getUserAgent(), request.getHeaders(), request.getVerb(), + request.getCompleteUrl(), filePayload, callback, converter); + } else if (request.getStringPayload() != null) { + return httpClient.executeAsync(config.getUserAgent(), request.getHeaders(), request.getVerb(), + request.getCompleteUrl(), request.getStringPayload(), callback, converter); + } else { + return httpClient.executeAsync(config.getUserAgent(), request.getHeaders(), request.getVerb(), + request.getCompleteUrl(), request.getByteArrayPayload(), callback, converter); + } + } + + public Response execute(OAuthRequest request) throws InterruptedException, ExecutionException, IOException { + final File filePayload = request.getFilePayload(); + if (filePayload != null) { + return httpClient.execute(config.getUserAgent(), request.getHeaders(), request.getVerb(), + request.getCompleteUrl(), filePayload); + } else if (request.getStringPayload() != null) { + return httpClient.execute(config.getUserAgent(), request.getHeaders(), request.getVerb(), + request.getCompleteUrl(), request.getStringPayload()); + } else { + return httpClient.execute(config.getUserAgent(), request.getHeaders(), request.getVerb(), + request.getCompleteUrl(), request.getByteArrayPayload()); + } + } } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/utils/MapUtils.java b/scribejava-core/src/main/java/com/github/scribejava/core/utils/MapUtils.java index bf48341fb..9cb217cb9 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/utils/MapUtils.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/utils/MapUtils.java @@ -14,8 +14,12 @@ public static String toString(Map map) { final StringBuilder result = new StringBuilder(); for (Map.Entry entry : map.entrySet()) { - result.append(String.format(", %s -> %s ", entry.getKey().toString(), entry.getValue().toString())); + result.append(", ") + .append(entry.getKey().toString()) + .append(" -> ") + .append(entry.getValue().toString()) + .append(' '); } - return "{" + result.substring(1) + "}"; + return "{" + result.append('}').substring(1); } } diff --git a/scribejava-core/src/main/java/com/github/scribejava/core/utils/Preconditions.java b/scribejava-core/src/main/java/com/github/scribejava/core/utils/Preconditions.java index 0858fc89d..19e1df083 100644 --- a/scribejava-core/src/main/java/com/github/scribejava/core/utils/Preconditions.java +++ b/scribejava-core/src/main/java/com/github/scribejava/core/utils/Preconditions.java @@ -1,9 +1,5 @@ package com.github.scribejava.core.utils; -import java.util.Locale; -import java.util.regex.Pattern; -import com.github.scribejava.core.model.OAuthConstants; - /** * Utils for checking preconditions and invariants */ @@ -11,9 +7,6 @@ public abstract class Preconditions { private static final String DEFAULT_MESSAGE = "Received an invalid parameter"; - // scheme = alpha *( alpha | digit | "+" | "-" | "." ) - private static final String URL_REGEXP = "^[a-zA-Z][a-zA-Z0-9+.-]*://\\S+"; - /** * Checks that an object is not null. * @@ -35,40 +28,25 @@ public static void checkNotNull(Object object, String errorMsg) { * @throws IllegalArgumentException if the string is null or empty */ public static void checkEmptyString(String string, String errorMsg) { - check(string != null && !string.trim().isEmpty(), errorMsg); - } - - /** - * Checks that a URL is valid - * - * @param url any string - * @param errorMsg error message - */ - public static void checkValidUrl(String url, String errorMsg) { - checkEmptyString(url, errorMsg); - check(isUrl(url), errorMsg); + check(hasText(string), errorMsg); } - /** - * Checks that a URL is a valid OAuth callback - * - * @param url any string - * @param errorMsg error message - */ - public static void checkValidOAuthCallback(String url, String errorMsg) { - checkEmptyString(url, errorMsg); - if (url.toLowerCase(Locale.getDefault()).compareToIgnoreCase(OAuthConstants.OUT_OF_BAND) != 0) { - check(isUrl(url), errorMsg); + public static boolean hasText(String str) { + if (str == null || str.isEmpty()) { + return false; } - } - - private static boolean isUrl(String url) { - return Pattern.compile(URL_REGEXP).matcher(url).matches(); + final int strLen = str.length(); + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return true; + } + } + return false; } private static void check(boolean requirements, String error) { if (!requirements) { - throw new IllegalArgumentException(error == null || error.trim().length() <= 0 ? DEFAULT_MESSAGE : error); + throw new IllegalArgumentException(hasText(error) ? error : DEFAULT_MESSAGE); } } 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 93d089489..7a86318d2 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 @@ -16,25 +16,22 @@ public abstract class StreamUtils { * * @param is input stream * @return string contents + * @throws java.io.IOException in any. SocketTimeout in example */ - public static String getStreamContents(InputStream is) { + public static String getStreamContents(InputStream is) throws IOException { Preconditions.checkNotNull(is, "Cannot get String from a null object"); - try { - 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(); - } catch (IOException ioe) { - throw new IllegalStateException("Error while reading response body", ioe); + 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(); } /** @@ -42,14 +39,11 @@ public static String getStreamContents(InputStream is) { * * @param is input stream * @return string contents + * @throws java.io.IOException in any. SocketTimeout in example */ - public static String getGzipStreamContents(InputStream is) { + public static String getGzipStreamContents(InputStream is) throws IOException { Preconditions.checkNotNull(is, "Cannot get String from a null object"); - try { - final GZIPInputStream gis = new GZIPInputStream(is); - return getStreamContents(gis); - } catch (IOException ioe) { - throw new IllegalStateException("Error while reading response body", ioe); - } + final GZIPInputStream gis = new GZIPInputStream(is); + return getStreamContents(gis); } } diff --git a/scribejava-core/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider b/scribejava-core/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider new file mode 100644 index 000000000..7df053c24 --- /dev/null +++ b/scribejava-core/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider @@ -0,0 +1,2 @@ +com.github.scribejava.core.httpclient.jdk.JDKHttpProvider + diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/ObjectMother.java b/scribejava-core/src/test/java/com/github/scribejava/core/ObjectMother.java index 30482b2c6..07e4081ec 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/ObjectMother.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/ObjectMother.java @@ -1,16 +1,13 @@ package com.github.scribejava.core; -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.Verb; -import com.github.scribejava.core.oauth.OAuth20Service; public abstract class ObjectMother { public static OAuthRequest createSampleOAuthRequest() { - final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com", - new OAuth20Service(null, new OAuthConfig("test", "test"))); + final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com"); request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); @@ -19,8 +16,7 @@ public static OAuthRequest createSampleOAuthRequest() { } public static OAuthRequest createSampleOAuthRequestPort80() { - final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com:80", - new OAuth20Service(null, new OAuthConfig("test", "test"))); + final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com:80"); request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); @@ -29,8 +25,7 @@ public static OAuthRequest createSampleOAuthRequestPort80() { } public static OAuthRequest createSampleOAuthRequestPort80v2() { - final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com:80/test", - new OAuth20Service(null, new OAuthConfig("test", "test"))); + final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com:80/test"); request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); @@ -39,8 +34,7 @@ public static OAuthRequest createSampleOAuthRequestPort80v2() { } public static OAuthRequest createSampleOAuthRequestPort8080() { - final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com:8080", - new OAuth20Service(null, new OAuthConfig("test", "test"))); + final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com:8080"); request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); @@ -49,8 +43,7 @@ public static OAuthRequest createSampleOAuthRequestPort8080() { } public static OAuthRequest createSampleOAuthRequestPort443() { - final OAuthRequest request = new OAuthRequest(Verb.GET, "https://example.com:443", - new OAuth20Service(null, new OAuthConfig("test", "test"))); + final OAuthRequest request = new OAuthRequest(Verb.GET, "https://example.com:443"); request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); @@ -59,8 +52,7 @@ public static OAuthRequest createSampleOAuthRequestPort443() { } public static OAuthRequest createSampleOAuthRequestPort443v2() { - final OAuthRequest request = new OAuthRequest(Verb.GET, "https://example.com:443/test", - new OAuth20Service(null, new OAuthConfig("test", "test"))); + final OAuthRequest request = new OAuthRequest(Verb.GET, "https://example.com:443/test"); request.addOAuthParameter(OAuthConstants.TIMESTAMP, "123456"); request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "AS#$^*@&"); request.addOAuthParameter(OAuthConstants.CALLBACK, "http://example/callback"); diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/builder/ServiceBuilderTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/builder/ServiceBuilderTest.java index 9bf8f386f..c7d4a4dac 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/builder/ServiceBuilderTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/builder/ServiceBuilderTest.java @@ -6,7 +6,6 @@ import com.github.scribejava.core.builder.api.DefaultApi20; import com.github.scribejava.core.model.OAuthConfig; import com.github.scribejava.core.model.OAuthConstants; -import com.github.scribejava.core.model.SignatureType; import com.github.scribejava.core.oauth.OAuth20Service; public class ServiceBuilderTest { @@ -16,7 +15,7 @@ public class ServiceBuilderTest { @Before public void setUp() { - builder = new ServiceBuilder(); + builder = new ServiceBuilder("will override api_key by another later in test"); api = ApiMock.instance(); } @@ -28,7 +27,6 @@ public void shouldReturnConfigDefaultValues() { assertEquals(config.getApiKey(), "key"); assertEquals(config.getApiSecret(), "secret"); assertEquals(config.getCallback(), OAuthConstants.OUT_OF_BAND); - assertEquals(config.getSignatureType(), SignatureType.Header); } @Test @@ -41,16 +39,6 @@ public void shouldAcceptValidCallbackUrl() { assertEquals(config.getCallback(), "http://example.com"); } - @Test - public void shouldAcceptASignatureType() { - builder.apiKey("key").apiSecret("secret").signatureType(SignatureType.QueryString).build(api); - - final OAuthConfig config = api.getConfig(); - assertEquals(config.getApiKey(), "key"); - assertEquals(config.getApiSecret(), "secret"); - assertEquals(config.getSignatureType(), SignatureType.QueryString); - } - @Test(expected = IllegalArgumentException.class) public void shouldNotAcceptNullAsCallback() { builder.apiKey("key").apiSecret("secret").callback(null).build(api); @@ -90,7 +78,7 @@ public String getAccessTokenEndpoint() { } @Override - public String getAuthorizationUrl(OAuthConfig config) { + protected String getAuthorizationBaseUrl() { throw new UnsupportedOperationException("Not supported yet."); } } diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/BaseStringExtractorTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/BaseStringExtractorTest.java index 3eb4b7404..bc833db08 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/BaseStringExtractorTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/BaseStringExtractorTest.java @@ -5,10 +5,8 @@ import org.junit.Test; import com.github.scribejava.core.ObjectMother; import com.github.scribejava.core.exceptions.OAuthParametersMissingException; -import com.github.scribejava.core.model.OAuthConfig; import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.oauth.OAuth20Service; public class BaseStringExtractorTest { @@ -92,8 +90,7 @@ public void shouldThrowExceptionIfRquestIsNull() { @Test(expected = OAuthParametersMissingException.class) public void shouldThrowExceptionIfRquestHasNoOAuthParameters() { - final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com", - new OAuth20Service(null, new OAuthConfig("test", "test"))); + final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com"); extractor.extract(request); } diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/HeaderExtractorTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/HeaderExtractorTest.java index 8de9d5c50..c1658fc7e 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/HeaderExtractorTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/HeaderExtractorTest.java @@ -1,13 +1,12 @@ package com.github.scribejava.core.extractors; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; import com.github.scribejava.core.exceptions.OAuthParametersMissingException; -import com.github.scribejava.core.model.OAuthConfig; import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.oauth.OAuth20Service; import com.github.scribejava.core.ObjectMother; public class HeaderExtractorTest { @@ -24,16 +23,24 @@ public void setUp() { @Test public void shouldExtractStandardHeader() { final String header = extractor.extract(request); - try { - assertEquals("OAuth oauth_callback=\"http%3A%2F%2Fexample%2Fcallback\", " - + "oauth_signature=\"OAuth-Signature\", oauth_consumer_key=\"AS%23%24%5E%2A%40%26\", " - + "oauth_timestamp=\"123456\"", header); - } catch (AssertionError ae) { - //maybe this is OpenJDK 8? Different order of elements in HashMap while iterating'em. - assertEquals("OAuth oauth_signature=\"OAuth-Signature\", " - + "oauth_callback=\"http%3A%2F%2Fexample%2Fcallback\", " - + "oauth_consumer_key=\"AS%23%24%5E%2A%40%26\", oauth_timestamp=\"123456\"", header); - } + final String oauth = "OAuth "; + final String callback = "oauth_callback=\"http%3A%2F%2Fexample%2Fcallback\""; + final String signature = "oauth_signature=\"OAuth-Signature\""; + final String key = "oauth_consumer_key=\"AS%23%24%5E%2A%40%26\""; + final String timestamp = "oauth_timestamp=\"123456\""; + + assertTrue(header.startsWith(oauth)); + assertTrue(header.contains(callback)); + assertTrue(header.contains(signature)); + assertTrue(header.contains(key)); + assertTrue(header.contains(timestamp)); + // Assert that header only contains the checked elements above and nothing else + assertEquals(", , , ", + header.replaceFirst(oauth, "") + .replaceFirst(callback, "") + .replaceFirst(signature, "") + .replaceFirst(key, "") + .replaceFirst(timestamp, "")); } @Test(expected = IllegalArgumentException.class) @@ -43,8 +50,7 @@ public void shouldExceptionIfRequestIsNull() { @Test(expected = OAuthParametersMissingException.class) public void shouldExceptionIfRequestHasNoOAuthParams() { - final OAuthRequest emptyRequest = new OAuthRequest(Verb.GET, "http://example.com", - new OAuth20Service(null, new OAuthConfig("test", "test"))); + final OAuthRequest emptyRequest = new OAuthRequest(Verb.GET, "http://example.com"); extractor.extract(emptyRequest); } } diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth1AccessTokenExtractorTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth1AccessTokenExtractorTest.java index 7cf3feb95..36ac4cd2e 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth1AccessTokenExtractorTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth1AccessTokenExtractorTest.java @@ -1,9 +1,14 @@ package com.github.scribejava.core.extractors; +import com.github.scribejava.core.model.Response; import org.junit.Before; import org.junit.Test; import com.github.scribejava.core.exceptions.OAuthException; import com.github.scribejava.core.model.OAuth1Token; + +import java.io.IOException; +import java.util.Collections; + import static org.junit.Assert.assertEquals; public class OAuth1AccessTokenExtractorTest { @@ -16,58 +21,62 @@ public void setUp() { } @Test - public void shouldExtractTokenFromOAuthStandardResponse() { + public void shouldExtractTokenFromOAuthStandardResponse() throws IOException { final String response = "oauth_token=hh5s93j4hdidpola&oauth_token_secret=hdhd0244k9j7ao03"; - final OAuth1Token extracted = extractor.extract(response); + final OAuth1Token extracted = extractor.extract(ok(response)); assertEquals("hh5s93j4hdidpola", extracted.getToken()); assertEquals("hdhd0244k9j7ao03", extracted.getTokenSecret()); } @Test - public void shouldExtractTokenFromInvertedOAuthStandardResponse() { + public void shouldExtractTokenFromInvertedOAuthStandardResponse() throws IOException { final String response = "oauth_token_secret=hh5s93j4hdidpola&oauth_token=hdhd0244k9j7ao03"; - final OAuth1Token extracted = extractor.extract(response); + final OAuth1Token extracted = extractor.extract(ok(response)); assertEquals("hh5s93j4hdidpola", extracted.getTokenSecret()); assertEquals("hdhd0244k9j7ao03", extracted.getToken()); } @Test - public void shouldExtractTokenFromResponseWithCallbackConfirmed() { + public void shouldExtractTokenFromResponseWithCallbackConfirmed() throws IOException { final String response = "oauth_token=hh5s93j4hdidpola&oauth_token_secret=hdhd0244k9j7ao03" + "&callback_confirmed=true"; - final OAuth1Token extracted = extractor.extract(response); + final OAuth1Token extracted = extractor.extract(ok(response)); assertEquals("hh5s93j4hdidpola", extracted.getToken()); assertEquals("hdhd0244k9j7ao03", extracted.getTokenSecret()); } @Test - public void shouldExtractTokenWithEmptySecret() { + public void shouldExtractTokenWithEmptySecret() throws IOException { final String response = "oauth_token=hh5s93j4hdidpola&oauth_token_secret="; - final OAuth1Token extracted = extractor.extract(response); + final OAuth1Token extracted = extractor.extract(ok(response)); assertEquals("hh5s93j4hdidpola", extracted.getToken()); assertEquals("", extracted.getTokenSecret()); } @Test(expected = OAuthException.class) - public void shouldThrowExceptionIfTokenIsAbsent() { + public void shouldThrowExceptionIfTokenIsAbsent() throws IOException { final String response = "oauth_secret=hh5s93j4hdidpola&callback_confirmed=true"; - extractor.extract(response); + extractor.extract(ok(response)); } @Test(expected = OAuthException.class) - public void shouldThrowExceptionIfSecretIsAbsent() { + public void shouldThrowExceptionIfSecretIsAbsent() throws IOException { final String response = "oauth_token=hh5s93j4hdidpola&callback_confirmed=true"; - extractor.extract(response); + extractor.extract(ok(response)); } @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionIfResponseIsNull() { - extractor.extract(null); + public void shouldThrowExceptionIfResponseIsNull() throws IOException { + extractor.extract(ok(null)); } @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionIfResponseIsEmptyString() { + public void shouldThrowExceptionIfResponseIsEmptyString() throws IOException { final String response = ""; - extractor.extract(response); + extractor.extract(ok(response)); + } + + private static Response ok(String body) { + return new Response(200, /* message */ null, /* headers */ Collections.emptyMap(), body); } } diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth2AccessTokenExtractorTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth2AccessTokenExtractorTest.java index 8ed1707b3..7f2cd4ddd 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth2AccessTokenExtractorTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth2AccessTokenExtractorTest.java @@ -1,9 +1,14 @@ package com.github.scribejava.core.extractors; +import com.github.scribejava.core.model.Response; import org.junit.Before; import org.junit.Test; import com.github.scribejava.core.exceptions.OAuthException; import com.github.scribejava.core.model.OAuth2AccessToken; + +import java.io.IOException; +import java.util.Collections; + import static org.junit.Assert.assertEquals; public class OAuth2AccessTokenExtractorTest { @@ -16,44 +21,61 @@ public void setUp() { } @Test - public void shouldExtractTokenFromOAuthStandardResponse() { + public void shouldExtractTokenFromOAuthStandardResponse() throws IOException { final String response = "access_token=166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159" + "|RsXNdKrpxg8L6QNLWcs2TVTmcaE"; - final OAuth2AccessToken extracted = extractor.extract(response); + final OAuth2AccessToken extracted = extractor.extract(ok(response)); + assertEquals("166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE", + extracted.getAccessToken()); + } + + @Test + public void shouldExtractTokenFromResponseWithExpiresParam() throws IOException { + final String response = "access_token=166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159" + + "|RsXNdKrpxg8L6QNLWcs2TVTmcaE&expires_in=5108"; + final OAuth2AccessToken extracted = extractor.extract(ok(response)); assertEquals("166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE", extracted.getAccessToken()); + assertEquals(Integer.valueOf(5108), extracted.getExpiresIn()); } @Test - public void shouldExtractTokenFromResponseWithExpiresParam() { + public void shouldExtractTokenFromResponseWithExpiresAndRefreshParam() throws IOException { final String response = "access_token=166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159" - + "|RsXNdKrpxg8L6QNLWcs2TVTmcaE&expires=5108"; - final OAuth2AccessToken extracted = extractor.extract(response); + + "|RsXNdKrpxg8L6QNLWcs2TVTmcaE&expires_in=5108&token_type=bearer&refresh_token=166942940015970"; + final OAuth2AccessToken extracted = extractor.extract(ok(response)); assertEquals("166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE", extracted.getAccessToken()); + assertEquals(Integer.valueOf(5108), extracted.getExpiresIn()); + assertEquals("bearer", extracted.getTokenType()); + assertEquals("166942940015970", extracted.getRefreshToken()); } @Test - public void shouldExtractTokenFromResponseWithManyParameters() { + public void shouldExtractTokenFromResponseWithManyParameters() throws IOException { final String response = "access_token=foo1234&other_stuff=yeah_we_have_this_too&number=42"; - final OAuth2AccessToken extracted = extractor.extract(response); + final OAuth2AccessToken extracted = extractor.extract(ok(response)); assertEquals("foo1234", extracted.getAccessToken()); } @Test(expected = OAuthException.class) - public void shouldThrowExceptionIfTokenIsAbsent() { + public void shouldThrowExceptionIfTokenIsAbsent() throws IOException { final String response = "&expires=5108"; - extractor.extract(response); + extractor.extract(ok(response)); } @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionIfResponseIsNull() { - extractor.extract(null); + public void shouldThrowExceptionIfResponseIsNull() throws IOException { + extractor.extract(ok(null)); } @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionIfResponseIsEmptyString() { + public void shouldThrowExceptionIfResponseIsEmptyString() throws IOException { final String response = ""; - extractor.extract(response); + extractor.extract(ok(response)); + } + + private static Response ok(String body) { + return new Response(200, /* message */ null, /* headers */ Collections.emptyMap(), body); } } diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth2AccessTokenJsonExtractorTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth2AccessTokenJsonExtractorTest.java index 9b2098e6c..42f07e25f 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth2AccessTokenJsonExtractorTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/extractors/OAuth2AccessTokenJsonExtractorTest.java @@ -1,8 +1,15 @@ package com.github.scribejava.core.extractors; import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuth2AccessTokenErrorResponse; +import com.github.scribejava.core.model.Response; import org.junit.Test; + +import java.io.IOException; +import java.util.Collections; + import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; public class OAuth2AccessTokenJsonExtractorTest { @@ -10,18 +17,41 @@ public class OAuth2AccessTokenJsonExtractorTest { private final OAuth2AccessTokenJsonExtractor extractor = OAuth2AccessTokenJsonExtractor.instance(); @Test - public void shouldParseResponse() { - final OAuth2AccessToken token = extractor.extract(RESPONSE); + public void shouldParseResponse() throws IOException { + final OAuth2AccessToken token = extractor.extract(ok(RESPONSE)); assertEquals(token.getAccessToken(), "I0122HHJKLEM21F3WLPYHDKGKZULAUO4SGMV3ABKFTDT3T3X"); } @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionIfForNullParameters() { - extractor.extract(null); + public void shouldThrowExceptionIfForNullParameters() throws IOException { + extractor.extract(ok(null)); } @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionIfForEmptyStrings() { - extractor.extract(""); + public void shouldThrowExceptionIfForEmptyStrings() throws IOException { + extractor.extract(ok("")); + } + + @Test + public void shouldThrowExceptionIfResponseIsError() throws IOException { + final String body = "{" + + "\"error_description\":\"unknown, invalid, or expired refresh token\"," + + "\"error\":\"invalid_grant\"" + + "}"; + try { + extractor.extract(error(body)); + fail(); + } catch (OAuth2AccessTokenErrorResponse oaer) { + assertEquals(OAuth2AccessTokenErrorResponse.ErrorCode.invalid_grant, oaer.getErrorCode()); + assertEquals("unknown, invalid, or expired refresh token", oaer.getErrorDescription()); + } + } + + private static Response ok(String body) { + return new Response(200, /* message */ null, /* headers */ Collections.emptyMap(), body); + } + + private static Response error(String body) { + return new Response(400, /* message */ null, /* headers */ Collections.emptyMap(), body); } } diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/model/ConnectionStub.java b/scribejava-core/src/test/java/com/github/scribejava/core/model/ConnectionStub.java deleted file mode 100644 index b7465527d..000000000 --- a/scribejava-core/src/test/java/com/github/scribejava/core/model/ConnectionStub.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.github.scribejava.core.model; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ConnectionStub extends HttpURLConnection { - - private final Map headers = new HashMap<>(); - private final Map> responseHeaders = new HashMap<>(); - private int inputStreamCalled; - - public ConnectionStub() throws MalformedURLException { - super(new URL("http://example.com")); - } - - @Override - public void setRequestProperty(String key, String value) { - headers.put(key, value); - } - - @Override - public String getRequestProperty(String s) { - return headers.get(s); - } - - public Map getHeaders() { - return headers; - } - - @Override - public int getResponseCode() throws IOException { - return 200; - } - - @Override - public InputStream getInputStream() throws IOException { - inputStreamCalled++; - return new ByteArrayInputStream("contents".getBytes()); - } - - public int getTimesCalledInpuStream() { - return inputStreamCalled; - } - - @Override - public OutputStream getOutputStream() throws IOException { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - baos.write("contents".getBytes()); - return baos; - } - - @Override - public Map> getHeaderFields() { - return responseHeaders; - } - - public void addResponseHeader(String key, String value) { - responseHeaders.put(key, Arrays.asList(value)); - } - - @Override - public void connect() { - } - - @Override - public void disconnect() { - } - - @Override - public boolean usingProxy() { - return false; - } - -} diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/model/ForceTypeOfHttpRequestTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/model/ForceTypeOfHttpRequestTest.java deleted file mode 100644 index 9e60f3fb2..000000000 --- a/scribejava-core/src/test/java/com/github/scribejava/core/model/ForceTypeOfHttpRequestTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.github.scribejava.core.model; - -import java.util.concurrent.ExecutionException; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import com.github.scribejava.core.exceptions.OAuthException; -import com.github.scribejava.core.oauth.OAuth20Service; -import com.github.scribejava.core.oauth.OAuthService; - -public class ForceTypeOfHttpRequestTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private OAuthRequest request; - private OAuthRequestAsync requestAsync; - - @Before - public void setUp() { - ScribeJavaConfig.setForceTypeOfHttpRequests(ForceTypeOfHttpRequest.NONE); - final OAuthService oAuthService = new OAuth20Service(null, new OAuthConfig("test", "test")); - request = new OAuthRequest(Verb.GET, "http://example.com?qsparam=value&other+param=value+with+spaces", - oAuthService); - requestAsync = new OAuthRequestAsync(Verb.GET, "http://example.com?qsparam=value&other+param=value+with+spaces", - oAuthService); - } - - @Test - public void shouldNotSendSyncWithForceParameter() { - expectedException.expect(OAuthException.class); - expectedException.expectMessage("Cannot use sync operations, only async"); - ScribeJavaConfig.setForceTypeOfHttpRequests(ForceTypeOfHttpRequest.FORCE_ASYNC_ONLY_HTTP_REQUESTS); - request.send(); - } - - @Test - public void shouldNotSendAsyncWithForceParameter() throws ExecutionException, InterruptedException { - expectedException.expect(OAuthException.class); - expectedException.expectMessage("Cannot use async operations, only sync"); - ScribeJavaConfig.setForceTypeOfHttpRequests(ForceTypeOfHttpRequest.FORCE_SYNC_ONLY_HTTP_REQUESTS); - requestAsync.sendAsync(null).get(); - } -} diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/model/OAuthRequestTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/model/OAuthRequestTest.java index d1bae5bfa..0ea88985d 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/model/OAuthRequestTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/model/OAuthRequestTest.java @@ -3,7 +3,6 @@ import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; -import com.github.scribejava.core.oauth.OAuth20Service; public class OAuthRequestTest { @@ -11,8 +10,7 @@ public class OAuthRequestTest { @Before public void setUp() { - request = new OAuthRequest(Verb.GET, "http://example.com", - new OAuth20Service(null, new OAuthConfig("test", "test"))); + request = new OAuthRequest(Verb.GET, "http://example.com"); } @Test diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/model/RequestTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/model/RequestTest.java index 16b060000..274ccca23 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/model/RequestTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/model/RequestTest.java @@ -1,38 +1,23 @@ package com.github.scribejava.core.model; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; -import com.github.scribejava.core.oauth.OAuth20Service; -import com.github.scribejava.core.oauth.OAuthService; import java.net.MalformedURLException; public class RequestTest { private OAuthRequest getRequest; private OAuthRequest postRequest; - private ConnectionStub connection; - private OAuthService oAuthService; @Before public void setUp() throws MalformedURLException { - connection = new ConnectionStub(); - oAuthService = new OAuth20Service(null, new OAuthConfig("test", "test")); - postRequest = new OAuthRequest(Verb.POST, "http://example.com", oAuthService); + postRequest = new OAuthRequest(Verb.POST, "http://example.com"); postRequest.addBodyParameter("param", "value"); postRequest.addBodyParameter("param with spaces", "value with spaces"); - postRequest.setConnection(connection); - getRequest = new OAuthRequest(Verb.GET, "http://example.com?qsparam=value&other+param=value+with+spaces", - oAuthService); - getRequest.setConnection(connection); - } - @Test - public void shouldSetRequestVerb() { - getRequest.send(); - assertEquals("GET", connection.getRequestMethod()); + getRequest = new OAuthRequest(Verb.GET, "http://example.com?qsparam=value&other+param=value+with+spaces"); } @Test @@ -42,33 +27,21 @@ public void shouldGetQueryStringParameters() { assertTrue(getRequest.getQueryStringParams().contains(new Parameter("qsparam", "value"))); } - @Test - public void shouldAddRequestHeaders() { - getRequest.addHeader("Header", "1"); - getRequest.addHeader("Header2", "2"); - getRequest.send(); - assertEquals(2, getRequest.getHeaders().size()); - assertEquals(2, connection.getHeaders().size()); - } - @Test public void shouldSetBodyParamsAndAddContentLength() { - assertEquals("param=value¶m%20with%20spaces=value%20with%20spaces", postRequest.getBodyContents()); - postRequest.send(); - assertTrue(connection.getHeaders().containsKey("Content-Length")); + assertEquals("param=value¶m%20with%20spaces=value%20with%20spaces", + new String(postRequest.getByteArrayPayload())); } @Test public void shouldSetPayloadAndHeaders() { - postRequest.addPayload("PAYLOAD"); - postRequest.send(); - assertEquals("PAYLOAD", postRequest.getBodyContents()); - assertTrue(connection.getHeaders().containsKey("Content-Length")); + postRequest.setPayload("PAYLOAD"); + assertEquals("PAYLOAD", postRequest.getStringPayload()); } @Test public void shouldAllowAddingQuerystringParametersAfterCreation() { - final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com?one=val", oAuthService); + final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com?one=val"); request.addQuerystringParameter("two", "other val"); request.addQuerystringParameter("more", "params"); assertEquals(3, request.getQueryStringParams().size()); @@ -76,7 +49,7 @@ public void shouldAllowAddingQuerystringParametersAfterCreation() { @Test public void shouldReturnTheCompleteUrl() { - final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com?one=val", oAuthService); + final OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com?one=val"); request.addQuerystringParameter("two", "other val"); request.addQuerystringParameter("more", "params"); assertEquals("http://example.com?one=val&two=other%20val&more=params", request.getCompleteUrl()); @@ -86,37 +59,4 @@ public void shouldReturnTheCompleteUrl() { public void shouldHandleQueryStringSpaceEncodingProperly() { assertTrue(getRequest.getQueryStringParams().contains(new Parameter("other param", "value with spaces"))); } - - @Test - public void shouldAutomaticallyAddContentTypeForPostRequestsWithBytePayload() { - postRequest.addPayload("PAYLOAD".getBytes()); - postRequest.send(); - assertEquals(OAuthRequest.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type")); - } - - @Test - public void shouldAutomaticallyAddContentTypeForPostRequestsWithStringPayload() { - postRequest.addPayload("PAYLOAD"); - postRequest.send(); - assertEquals(OAuthRequest.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type")); - } - - @Test - public void shouldAutomaticallyAddContentTypeForPostRequestsWithBodyParameters() { - postRequest.send(); - assertEquals(OAuthRequest.DEFAULT_CONTENT_TYPE, connection.getHeaders().get("Content-Type")); - } - - @Test - public void shouldBeAbleToOverrideItsContentType() { - postRequest.addHeader("Content-Type", "my-content-type"); - postRequest.send(); - assertEquals("my-content-type", connection.getHeaders().get("Content-Type")); - } - - @Test - public void shouldNotAddContentTypeForGetRequests() { - getRequest.send(); - assertFalse(connection.getHeaders().containsKey("Content-Type")); - } } diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/model/ResponseTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/model/ResponseTest.java deleted file mode 100644 index c4fe5712f..000000000 --- a/scribejava-core/src/test/java/com/github/scribejava/core/model/ResponseTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.github.scribejava.core.model; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import static org.junit.Assert.assertEquals; -import org.junit.Before; -import org.junit.Test; - -public class ResponseTest { - - private Response response; - private ConnectionStub connection; - - @Before - public void setUp() throws IOException { - connection = new ConnectionStub(); - connection.addResponseHeader("one", "one"); - connection.addResponseHeader("two", "two"); - response = new Response(connection); - } - - @Test - public void shouldPopulateResponseHeaders() { - assertEquals(2, response.getHeaders().size()); - assertEquals("one", response.getHeader("one")); - } - - @Test - public void shouldParseBodyContents() { - assertEquals("contents", response.getBody()); - assertEquals(1, connection.getTimesCalledInpuStream()); - } - - @Test - public void shouldParseBodyContentsOnlyOnce() { - assertEquals("contents", response.getBody()); - assertEquals("contents", response.getBody()); - assertEquals("contents", response.getBody()); - assertEquals(1, connection.getTimesCalledInpuStream()); - } - - @Test - public void shouldHandleAConnectionWithErrors() throws IOException { - final Response errResponse = new Response(new FaultyConnection()); - assertEquals(400, errResponse.getCode()); - assertEquals("errors", errResponse.getBody()); - } - - private static class FaultyConnection extends ConnectionStub { - - private FaultyConnection() throws MalformedURLException { - super(); - } - - @Override - public InputStream getErrorStream() { - return new ByteArrayInputStream("errors".getBytes()); - } - - @Override - public int getResponseCode() throws IOException { - return 400; - } - } -} diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/oauth/CompletedFuture.java b/scribejava-core/src/test/java/com/github/scribejava/core/oauth/CompletedFuture.java new file mode 100644 index 000000000..33919d4bf --- /dev/null +++ b/scribejava-core/src/test/java/com/github/scribejava/core/oauth/CompletedFuture.java @@ -0,0 +1,37 @@ +package com.github.scribejava.core.oauth; + +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +class CompletedFuture implements Future { + private final V result; + + CompletedFuture(V result) { + this.result = result; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return true; + } + + @Override + public V get() { + return result; + } + + @Override + public V get(long timeout, TimeUnit unit) { + return result; + } +} diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/oauth/OAuth20ApiUnit.java b/scribejava-core/src/test/java/com/github/scribejava/core/oauth/OAuth20ApiUnit.java new file mode 100644 index 000000000..c6c05e05c --- /dev/null +++ b/scribejava-core/src/test/java/com/github/scribejava/core/oauth/OAuth20ApiUnit.java @@ -0,0 +1,28 @@ +package com.github.scribejava.core.oauth; + +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.builder.api.OAuth2SignatureType; +import com.github.scribejava.core.model.OAuthConfig; + +class OAuth20ApiUnit extends DefaultApi20 { + + @Override + public String getAccessTokenEndpoint() { + return "http://localhost:8080/token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return "http://localhost:8080/authorize"; + } + + @Override + public OAuth20Service createService(OAuthConfig config) { + return new OAuth20ServiceUnit(this, config); + } + + @Override + public OAuth2SignatureType getSignatureType() { + return OAuth2SignatureType.BEARER_URI_QUERY_PARAMETER; + } +} diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/oauth/OAuth20ServiceTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/oauth/OAuth20ServiceTest.java new file mode 100644 index 000000000..581fc5a63 --- /dev/null +++ b/scribejava-core/src/test/java/com/github/scribejava/core/oauth/OAuth20ServiceTest.java @@ -0,0 +1,131 @@ +package com.github.scribejava.core.oauth; + +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuth2Authorization; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.services.Base64Encoder; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import java.io.IOException; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +import java.nio.charset.Charset; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +public class OAuth20ServiceTest { + + @Test + public void shouldProduceCorrectRequestSync() throws IOException, InterruptedException, ExecutionException { + final OAuth20Service service = new ServiceBuilder("your_api_key") + .apiSecret("your_api_secret") + .build(new OAuth20ApiUnit()); + + final OAuth2AccessToken token = service.getAccessTokenPasswordGrant("user1", "password1"); + final Gson json = new Gson(); + + assertNotNull(token); + + final Map map = json.fromJson(token.getRawResponse(), new TypeTokenImpl().getType()); + + assertEquals(OAuth20ServiceUnit.TOKEN, map.get(OAuthConstants.ACCESS_TOKEN)); + assertEquals(OAuth20ServiceUnit.STATE, map.get(OAuthConstants.STATE)); + assertEquals(OAuth20ServiceUnit.EXPIRES, map.get("expires_in")); + + final String authorize = Base64Encoder.getInstance() + .encode(String.format("%s:%s", service.getConfig().getApiKey(), service.getConfig().getApiSecret()) + .getBytes(Charset.forName("UTF-8"))); + + assertEquals(OAuthConstants.BASIC + " " + authorize, map.get(OAuthConstants.HEADER)); + + assertEquals("user1", map.get("query-username")); + assertEquals("password1", map.get("query-password")); + assertEquals("password", map.get("query-grant_type")); + } + + @Test + public void shouldProduceCorrectRequestAsync() throws ExecutionException, InterruptedException { + final OAuth20Service service = new ServiceBuilder("your_api_key") + .apiSecret("your_api_secret") + .build(new OAuth20ApiUnit()); + + final OAuth2AccessToken token = service.getAccessTokenPasswordGrantAsync("user1", "password1", null).get(); + final Gson json = new Gson(); + + assertNotNull(token); + + final Map map = json.fromJson(token.getRawResponse(), new TypeTokenImpl().getType()); + + assertEquals(OAuth20ServiceUnit.TOKEN, map.get(OAuthConstants.ACCESS_TOKEN)); + assertEquals(OAuth20ServiceUnit.STATE, map.get(OAuthConstants.STATE)); + assertEquals(OAuth20ServiceUnit.EXPIRES, map.get("expires_in")); + + final String authorize = Base64Encoder.getInstance() + .encode(String.format("%s:%s", service.getConfig().getApiKey(), service.getConfig().getApiSecret()) + .getBytes(Charset.forName("UTF-8"))); + + assertEquals(OAuthConstants.BASIC + " " + authorize, map.get(OAuthConstants.HEADER)); + + assertEquals("user1", map.get("query-username")); + assertEquals("password1", map.get("query-password")); + assertEquals("password", map.get("query-grant_type")); + } + + @Test + public void testOAuthExtractAuthorization() { + final OAuth20Service service = new ServiceBuilder("your_api_key") + .apiSecret("your_api_secret") + .build(new OAuth20ApiUnit()); + + OAuth2Authorization authorization = service.extractAuthorization("https://cl.ex.com/cb?code=SplxlOB&state=xyz"); + assertEquals("SplxlOB", authorization.getCode()); + assertEquals("xyz", authorization.getState()); + + authorization = service.extractAuthorization("https://cl.ex.com/cb?state=xyz&code=SplxlOB"); + assertEquals("SplxlOB", authorization.getCode()); + assertEquals("xyz", authorization.getState()); + + authorization = service.extractAuthorization("https://cl.ex.com/cb?key=value&state=xyz&code=SplxlOB"); + assertEquals("SplxlOB", authorization.getCode()); + assertEquals("xyz", authorization.getState()); + + authorization = service.extractAuthorization("https://cl.ex.com/cb?state=xyz&code=SplxlOB&key=value&"); + assertEquals("SplxlOB", authorization.getCode()); + assertEquals("xyz", authorization.getState()); + + authorization = service.extractAuthorization("https://cl.ex.com/cb?code=SplxlOB&state="); + assertEquals("SplxlOB", authorization.getCode()); + assertEquals(null, authorization.getState()); + + authorization = service.extractAuthorization("https://cl.ex.com/cb?code=SplxlOB"); + assertEquals("SplxlOB", authorization.getCode()); + assertEquals(null, authorization.getState()); + + authorization = service.extractAuthorization("https://cl.ex.com/cb?code="); + assertEquals(null, authorization.getCode()); + assertEquals(null, authorization.getState()); + + authorization = service.extractAuthorization("https://cl.ex.com/cb?code"); + assertEquals(null, authorization.getCode()); + assertEquals(null, authorization.getState()); + + authorization = service.extractAuthorization("https://cl.ex.com/cb?"); + assertEquals(null, authorization.getCode()); + assertEquals(null, authorization.getState()); + + authorization = service.extractAuthorization("https://cl.ex.com/cb"); + assertEquals(null, authorization.getCode()); + assertEquals(null, authorization.getState()); + + } + + private static class TypeTokenImpl extends TypeToken> { + + private TypeTokenImpl() { + } + } + +} diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/oauth/OAuth20ServiceUnit.java b/scribejava-core/src/test/java/com/github/scribejava/core/oauth/OAuth20ServiceUnit.java new file mode 100644 index 000000000..8a49c0ee1 --- /dev/null +++ b/scribejava-core/src/test/java/com/github/scribejava/core/oauth/OAuth20ServiceUnit.java @@ -0,0 +1,62 @@ +package com.github.scribejava.core.oauth; + +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.model.OAuth2AccessToken; +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.Parameter; +import com.google.gson.Gson; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Future; + +class OAuth20ServiceUnit extends OAuth20Service { + + static final String TOKEN = "ae82980abab675c646a070686d5558ad"; + static final String STATE = "123"; + static final String EXPIRES = "3600"; + + OAuth20ServiceUnit(DefaultApi20 api, OAuthConfig config) { + super(api, config); + } + + @Override + protected OAuth2AccessToken sendAccessTokenRequestSync(OAuthRequest request) { + return new OAuth2AccessToken(TOKEN, prepareRawResponse(request)); + } + + private String prepareRawResponse(OAuthRequest request) { + final Gson json = new Gson(); + final Map response = new HashMap<>(); + response.put(OAuthConstants.ACCESS_TOKEN, TOKEN); + response.put(OAuthConstants.STATE, STATE); + response.put("expires_in", EXPIRES); + + response.putAll(request.getHeaders()); + response.putAll(request.getOauthParameters()); + + for (Parameter p : request.getBodyParams().getParams()) { + response.put("query-" + p.getKey(), p.getValue()); + } + + return json.toJson(response); + } + + @Override + protected Future sendAccessTokenRequestAsync(OAuthRequest request, + OAuthAsyncRequestCallback callback) { + + final OAuth2AccessToken accessToken = new OAuth2AccessToken(TOKEN, prepareRawResponse(request)); + + try { + return new CompletedFuture<>(accessToken); + } finally { + if (callback != null) { + callback.onCompleted(accessToken); + } + } + } +} diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/utils/MapUtilsTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/utils/MapUtilsTest.java index dc6bd38d5..9ce36c76f 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/utils/MapUtilsTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/utils/MapUtilsTest.java @@ -1,5 +1,6 @@ package com.github.scribejava.core.utils; +import java.util.LinkedHashMap; import java.util.HashMap; import java.util.Map; import org.junit.Assert; @@ -9,7 +10,7 @@ public class MapUtilsTest { @Test public void shouldPrettyPrintMap() { - final Map map = new HashMap<>(); + final Map map = new LinkedHashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/utils/PreconditionsTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/utils/PreconditionsTest.java index 76d64c5ba..ec6722c5a 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/utils/PreconditionsTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/utils/PreconditionsTest.java @@ -25,49 +25,4 @@ public void shouldThrowExceptionForEmptyStrings() { public void shouldThrowExceptionForSpacesOnlyStrings() { Preconditions.checkEmptyString(" ", ERROR_MSG); } - - @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionForInvalidUrls() { - Preconditions.checkValidUrl("this/is/not/a/valid/url", ERROR_MSG); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldThrowExceptionForNullUrls() { - Preconditions.checkValidUrl(null, ERROR_MSG); - } - - @Test - public void shouldAllowValidUrls() { - Preconditions.checkValidUrl("http://www.example.com", ERROR_MSG); - } - - @Test - public void shouldAllowSSLUrls() { - Preconditions.checkValidUrl("https://www.example.com", ERROR_MSG); - } - - @Test - public void shouldAllowSpecialCharsInScheme() { - Preconditions.checkValidUrl("custom+9.3-1://www.example.com", ERROR_MSG); - } - - @Test - public void shouldAllowNonStandarProtocolsForAndroid() { - Preconditions.checkValidUrl("x-url-custom://www.example.com", ERROR_MSG); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldNotAllowStrangeProtocolNames() { - Preconditions.checkValidUrl("$weird*://www.example.com", ERROR_MSG); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldNotAllowUnderscoreInScheme() { - Preconditions.checkValidUrl("http_custom://www.example.com", ERROR_MSG); - } - - @Test - public void shouldAllowOutOfBandAsValidCallbackValue() { - Preconditions.checkValidOAuthCallback("oob", ERROR_MSG); - } } diff --git a/scribejava-core/src/test/java/com/github/scribejava/core/utils/StreamUtilsTest.java b/scribejava-core/src/test/java/com/github/scribejava/core/utils/StreamUtilsTest.java index 322283d23..cb5c6c7c9 100644 --- a/scribejava-core/src/test/java/com/github/scribejava/core/utils/StreamUtilsTest.java +++ b/scribejava-core/src/test/java/com/github/scribejava/core/utils/StreamUtilsTest.java @@ -20,7 +20,7 @@ public int read() throws IOException { } @Test - public void shouldCorrectlyDecodeAStream() { + public void shouldCorrectlyDecodeAStream() throws IOException { final String value = "expected"; final InputStream is = new ByteArrayInputStream(value.getBytes()); final String decoded = StreamUtils.getStreamContents(is); @@ -28,13 +28,13 @@ public void shouldCorrectlyDecodeAStream() { } @Test(expected = IllegalArgumentException.class) - public void shouldFailForNullParameter() { + public void shouldFailForNullParameter() throws IOException { StreamUtils.getStreamContents(null); fail("Must throw exception before getting here"); } - @Test(expected = IllegalStateException.class) - public void shouldFailWithBrokenStream() { + @Test(expected = IOException.class) + public void shouldFailWithBrokenStream() throws IOException { // This object simulates problems with input stream. StreamUtils.getStreamContents(ALLWAYS_ERROR_INPUT_STREAM); fail("Must throw exception before getting here"); diff --git a/scribejava-httpclient-ahc/pom.xml b/scribejava-httpclient-ahc/pom.xml new file mode 100644 index 000000000..1a42399a4 --- /dev/null +++ b/scribejava-httpclient-ahc/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + + com.github.scribejava + scribejava + 4.1.2-SNAPSHOT + ../pom.xml + + + com.github.scribejava + scribejava-httpclient-ahc + ScribeJava Async Http Http Client support + jar + + + + com.github.scribejava + scribejava-core + ${project.version} + + + org.asynchttpclient + async-http-client + 2.0.32 + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + diff --git a/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/AhcHttpClient.java b/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/AhcHttpClient.java new file mode 100644 index 000000000..cdc894bb8 --- /dev/null +++ b/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/AhcHttpClient.java @@ -0,0 +1,118 @@ +package com.github.scribejava.httpclient.ahc; + +import com.github.scribejava.core.httpclient.AbstractAsyncOnlyHttpClient; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Verb; +import org.asynchttpclient.AsyncHttpClient; +import org.asynchttpclient.DefaultAsyncHttpClient; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.Future; + +import java.io.File; +import org.asynchttpclient.AsyncHttpClientConfig; +import org.asynchttpclient.BoundRequestBuilder; + +public class AhcHttpClient extends AbstractAsyncOnlyHttpClient { + + private final AsyncHttpClient client; + + public AhcHttpClient(AhcHttpClientConfig ahcConfig) { + final AsyncHttpClientConfig clientConfig = ahcConfig.getClientConfig(); + client = clientConfig == null ? new DefaultAsyncHttpClient() : new DefaultAsyncHttpClient(clientConfig); + } + + public AhcHttpClient(AsyncHttpClient ahcClient) { + client = ahcClient; + } + + @Override + public void close() throws IOException { + client.close(); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodySetter.BYTE_ARRAY, bodyContents, callback, + converter); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodySetter.STRING, bodyContents, callback, + converter); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodySetter.FILE, bodyContents, callback, + converter); + } + + private Future doExecuteAsync(String userAgent, Map headers, Verb httpVerb, + String completeUrl, BodySetter bodySetter, Object bodyContents, OAuthAsyncRequestCallback callback, + OAuthRequest.ResponseConverter converter) { + BoundRequestBuilder boundRequestBuilder; + switch (httpVerb) { + case GET: + boundRequestBuilder = client.prepareGet(completeUrl); + break; + case POST: + boundRequestBuilder = client.preparePost(completeUrl); + break; + case PUT: + boundRequestBuilder = client.preparePut(completeUrl); + break; + case DELETE: + boundRequestBuilder = client.prepareDelete(completeUrl); + break; + default: + throw new IllegalArgumentException("message build error: unknown verb type"); + } + + if (httpVerb.isPermitBody()) { + if (!headers.containsKey(CONTENT_TYPE)) { + boundRequestBuilder = boundRequestBuilder.addHeader(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); + } + boundRequestBuilder = bodySetter.setBody(boundRequestBuilder, bodyContents); + } + + 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 OAuthAsyncCompletionHandler<>(callback, converter)); + } + + private enum BodySetter { + BYTE_ARRAY { + @Override + BoundRequestBuilder setBody(BoundRequestBuilder requestBuilder, Object bodyContents) { + return requestBuilder.setBody((byte[]) bodyContents); + } + }, + STRING { + @Override + BoundRequestBuilder setBody(BoundRequestBuilder requestBuilder, Object bodyContents) { + return requestBuilder.setBody((String) bodyContents); + } + }, + FILE { + @Override + BoundRequestBuilder setBody(BoundRequestBuilder requestBuilder, Object bodyContents) { + return requestBuilder.setBody((File) bodyContents); + } + }; + + abstract BoundRequestBuilder setBody(BoundRequestBuilder requestBuilder, Object bodyContents); + } +} diff --git a/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/AhcHttpClientConfig.java b/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/AhcHttpClientConfig.java new file mode 100644 index 000000000..490eaf2e6 --- /dev/null +++ b/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/AhcHttpClientConfig.java @@ -0,0 +1,26 @@ +package com.github.scribejava.httpclient.ahc; + +import com.github.scribejava.core.httpclient.HttpClientConfig; +import org.asynchttpclient.AsyncHttpClientConfig; + +public class AhcHttpClientConfig implements HttpClientConfig { + + private final AsyncHttpClientConfig clientConfig; + + public AhcHttpClientConfig(AsyncHttpClientConfig clientConfig) { + this.clientConfig = clientConfig; + } + + public AsyncHttpClientConfig getClientConfig() { + return clientConfig; + } + + @Override + public AhcHttpClientConfig createDefaultConfig() { + return defaultConfig(); + } + + public static AhcHttpClientConfig defaultConfig() { + return new AhcHttpClientConfig(null); + } +} diff --git a/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/AhcProvider.java b/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/AhcProvider.java new file mode 100644 index 000000000..97c21dc86 --- /dev/null +++ b/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/AhcProvider.java @@ -0,0 +1,16 @@ +package com.github.scribejava.httpclient.ahc; + +import com.github.scribejava.core.httpclient.HttpClientProvider; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.HttpClientConfig; + +public class AhcProvider implements HttpClientProvider { + + @Override + public HttpClient createClient(HttpClientConfig config) { + if (config instanceof AhcHttpClientConfig) { + return new AhcHttpClient((AhcHttpClientConfig) config); + } + return null; + } +} diff --git a/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/OAuthAsyncCompletionHandler.java b/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/OAuthAsyncCompletionHandler.java new file mode 100644 index 000000000..856cbcf68 --- /dev/null +++ b/scribejava-httpclient-ahc/src/main/java/com/github/scribejava/httpclient/ahc/OAuthAsyncCompletionHandler.java @@ -0,0 +1,47 @@ +package com.github.scribejava.httpclient.ahc; + +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthRequest; +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 OAuthRequest.ResponseConverter converter; + + public OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback callback, + OAuthRequest.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.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-httpclient-ahc/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider b/scribejava-httpclient-ahc/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider new file mode 100644 index 000000000..bbe752ff6 --- /dev/null +++ b/scribejava-httpclient-ahc/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider @@ -0,0 +1 @@ +com.github.scribejava.httpclient.ahc.AhcProvider diff --git a/scribejava-httpclient-ning/pom.xml b/scribejava-httpclient-ning/pom.xml new file mode 100644 index 000000000..462ca93db --- /dev/null +++ b/scribejava-httpclient-ning/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + + com.github.scribejava + scribejava + 4.1.2-SNAPSHOT + ../pom.xml + + + com.github.scribejava + scribejava-httpclient-ning + ScribeJava Ning Async Http Client support + jar + + + + com.github.scribejava + scribejava-core + ${project.version} + + + com.ning + async-http-client + 1.9.40 + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + diff --git a/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClient.java b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClient.java new file mode 100644 index 000000000..bcc843e00 --- /dev/null +++ b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClient.java @@ -0,0 +1,130 @@ +package com.github.scribejava.httpclient.ning; + +import com.github.scribejava.core.httpclient.AbstractAsyncOnlyHttpClient; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Verb; +import com.ning.http.client.AsyncHttpClient; + +import java.util.Map; +import java.util.concurrent.Future; + +import com.ning.http.client.AsyncHttpClientConfig; +import java.io.File; + +public class NingHttpClient extends AbstractAsyncOnlyHttpClient { + + private final AsyncHttpClient client; + + public NingHttpClient(NingHttpClientConfig ningConfig) { + final String ningAsyncHttpProviderClassName = ningConfig.getNingAsyncHttpProviderClassName(); + AsyncHttpClientConfig config = ningConfig.getConfig(); + if (ningAsyncHttpProviderClassName == null) { + client = config == null ? new AsyncHttpClient() : new AsyncHttpClient(config); + } else { + if (config == null) { + config = new AsyncHttpClientConfig.Builder().build(); + } + client = new AsyncHttpClient(ningAsyncHttpProviderClassName, config); + } + } + + public NingHttpClient(AsyncHttpClient client) { + this.client = client; + } + + @Override + public void close() { + client.close(); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodySetter.BYTE_ARRAY, bodyContents, callback, + converter); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodySetter.STRING, bodyContents, callback, + converter); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodySetter.FILE, bodyContents, callback, + converter); + } + + private Future doExecuteAsync(String userAgent, Map headers, Verb httpVerb, + String completeUrl, BodySetter bodySetter, Object bodyContents, OAuthAsyncRequestCallback callback, + OAuthRequest.ResponseConverter converter) { + AsyncHttpClient.BoundRequestBuilder boundRequestBuilder; + switch (httpVerb) { + case GET: + boundRequestBuilder = client.prepareGet(completeUrl); + break; + case POST: + boundRequestBuilder = client.preparePost(completeUrl); + break; + case PUT: + boundRequestBuilder = client.preparePut(completeUrl); + break; + case DELETE: + boundRequestBuilder = client.prepareDelete(completeUrl); + break; + default: + throw new IllegalArgumentException("message build error: unknown verb type"); + } + + if (httpVerb.isPermitBody()) { + if (!headers.containsKey(CONTENT_TYPE)) { + boundRequestBuilder = boundRequestBuilder.addHeader(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); + } + boundRequestBuilder = bodySetter.setBody(boundRequestBuilder, bodyContents); + } + + 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 OAuthAsyncCompletionHandler<>(callback, converter)); + } + + private enum BodySetter { + BYTE_ARRAY { + @Override + AsyncHttpClient.BoundRequestBuilder setBody(AsyncHttpClient.BoundRequestBuilder requestBuilder, + Object bodyContents) { + return requestBuilder.setBody((byte[]) bodyContents); + } + }, + STRING { + @Override + AsyncHttpClient.BoundRequestBuilder setBody(AsyncHttpClient.BoundRequestBuilder requestBuilder, + Object bodyContents) { + return requestBuilder.setBody((String) bodyContents); + } + }, + FILE { + @Override + AsyncHttpClient.BoundRequestBuilder setBody(AsyncHttpClient.BoundRequestBuilder requestBuilder, + Object bodyContents) { + return requestBuilder.setBody((File) bodyContents); + } + }; + + abstract AsyncHttpClient.BoundRequestBuilder setBody(AsyncHttpClient.BoundRequestBuilder requestBuilder, + Object bodyContents); + } +} diff --git a/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClientConfig.java b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClientConfig.java new file mode 100644 index 000000000..9eb5d83c2 --- /dev/null +++ b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClientConfig.java @@ -0,0 +1,35 @@ +package com.github.scribejava.httpclient.ning; + +import com.github.scribejava.core.httpclient.HttpClientConfig; +import com.ning.http.client.AsyncHttpClientConfig; + +public class NingHttpClientConfig implements HttpClientConfig { + + private final AsyncHttpClientConfig config; + private String ningAsyncHttpProviderClassName; + + public NingHttpClientConfig(AsyncHttpClientConfig config) { + this.config = config; + } + + public String getNingAsyncHttpProviderClassName() { + return ningAsyncHttpProviderClassName; + } + + public void setNingAsyncHttpProviderClassName(String ningAsyncHttpProviderClassName) { + this.ningAsyncHttpProviderClassName = ningAsyncHttpProviderClassName; + } + + public AsyncHttpClientConfig getConfig() { + return config; + } + + @Override + public NingHttpClientConfig createDefaultConfig() { + return defaultConfig(); + } + + public static NingHttpClientConfig defaultConfig() { + return new NingHttpClientConfig(null); + } +} diff --git a/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingProvider.java b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingProvider.java new file mode 100644 index 000000000..2db967249 --- /dev/null +++ b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingProvider.java @@ -0,0 +1,16 @@ +package com.github.scribejava.httpclient.ning; + +import com.github.scribejava.core.httpclient.HttpClientProvider; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.HttpClientConfig; + +public class NingProvider implements HttpClientProvider { + + @Override + public HttpClient createClient(HttpClientConfig httpClientConfig) { + if (httpClientConfig instanceof NingHttpClientConfig) { + return new NingHttpClient((NingHttpClientConfig) httpClientConfig); + } + return null; + } +} diff --git a/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/OAuthAsyncCompletionHandler.java b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/OAuthAsyncCompletionHandler.java new file mode 100644 index 000000000..5ce461b1b --- /dev/null +++ b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/OAuthAsyncCompletionHandler.java @@ -0,0 +1,52 @@ +package com.github.scribejava.httpclient.ning; + +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthRequest; +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 OAuthRequest.ResponseConverter converter; + + public OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback callback, + OAuthRequest.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.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-httpclient-ning/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider b/scribejava-httpclient-ning/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider new file mode 100644 index 000000000..9f6843994 --- /dev/null +++ b/scribejava-httpclient-ning/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider @@ -0,0 +1 @@ +com.github.scribejava.httpclient.ning.NingProvider diff --git a/scribejava-httpclient-okhttp/pom.xml b/scribejava-httpclient-okhttp/pom.xml new file mode 100644 index 000000000..0427e8d9a --- /dev/null +++ b/scribejava-httpclient-okhttp/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + + com.github.scribejava + scribejava + 4.1.2-SNAPSHOT + ../pom.xml + + + com.github.scribejava + scribejava-httpclient-okhttp + ScribeJava Async OkHttp Client support + jar + + + + com.github.scribejava + scribejava-core + ${project.version} + + + com.squareup.okhttp3 + okhttp + 3.8.0 + + + com.squareup.okhttp3 + mockwebserver + 3.8.0 + test + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + diff --git a/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OAuthAsyncCompletionHandler.java b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OAuthAsyncCompletionHandler.java new file mode 100644 index 000000000..af59abbb5 --- /dev/null +++ b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OAuthAsyncCompletionHandler.java @@ -0,0 +1,51 @@ +package com.github.scribejava.httpclient.okhttp; + +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import okhttp3.Call; +import okhttp3.Callback; + +import java.io.IOException; + +class OAuthAsyncCompletionHandler implements Callback { + + private final OAuthAsyncRequestCallback callback; + private final OAuthRequest.ResponseConverter converter; + private final OkHttpFuture okHttpFuture; + + OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter, + OkHttpFuture okHttpFuture) { + this.callback = callback; + this.converter = converter; + this.okHttpFuture = okHttpFuture; + } + + @Override + public void onFailure(Call call, IOException e) { + try { + if (callback != null) { + callback.onThrowable(e); + } + } finally { + okHttpFuture.finish(); + } + } + + @Override + public void onResponse(Call call, okhttp3.Response okHttpResponse) throws IOException { + try { + + final Response response = OkHttpHttpClient.convertResponse(okHttpResponse); + + @SuppressWarnings("unchecked") + final T t = converter == null ? (T) response : converter.convert(response); + okHttpFuture.setResult(t); + if (callback != null) { + callback.onCompleted(t); + } + } finally { + okHttpFuture.finish(); + } + } +} diff --git a/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpFuture.java b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpFuture.java new file mode 100644 index 000000000..ebf459260 --- /dev/null +++ b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpFuture.java @@ -0,0 +1,59 @@ +package com.github.scribejava.httpclient.okhttp; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import okhttp3.Call; + +public class OkHttpFuture implements Future { + + private final CountDownLatch latch = new CountDownLatch(1); + private final Call call; + private T result; + + public OkHttpFuture(Call call) { + this.call = call; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + call.cancel(); + return call.isCanceled(); + } + + @Override + public boolean isCancelled() { + return call.isCanceled(); + } + + @Override + public boolean isDone() { + return call.isExecuted(); + } + + @Override + public T get() throws InterruptedException, ExecutionException { + latch.await(); + return result; + } + + @Override + public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + if (latch.await(timeout, unit)) { + return result; + } else { + throw new TimeoutException(); + } + } + + void finish() { + latch.countDown(); + } + + void setResult(T result) { + this.result = result; + } + +} diff --git a/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpHttpClient.java b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpHttpClient.java new file mode 100644 index 000000000..66d2daee0 --- /dev/null +++ b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpHttpClient.java @@ -0,0 +1,175 @@ +package com.github.scribejava.httpclient.okhttp; + +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.model.OAuthAsyncRequestCallback; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Verb; +import okhttp3.Call; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.internal.http.HttpMethod; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.Future; + +import com.github.scribejava.core.model.Response; +import java.io.File; +import java.util.HashMap; +import java.util.concurrent.ExecutionException; +import okhttp3.Cache; +import okhttp3.Headers; +import okhttp3.ResponseBody; + +public class OkHttpHttpClient implements HttpClient { + + private static final MediaType DEFAULT_CONTENT_TYPE_MEDIA_TYPE = MediaType.parse(DEFAULT_CONTENT_TYPE); + + private final OkHttpClient client; + + public OkHttpHttpClient(OkHttpHttpClientConfig config) { + final OkHttpClient.Builder clientBuilder = config.getClientBuilder(); + client = clientBuilder == null ? new OkHttpClient() : clientBuilder.build(); + } + + public OkHttpHttpClient(OkHttpClient client) { + this.client = client; + } + + @Override + public void close() throws IOException { + client.dispatcher().executorService().shutdown(); + client.connectionPool().evictAll(); + final Cache cache = client.cache(); + if (cache != null) { + cache.close(); + } + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.BYTE_ARRAY, bodyContents, callback, + converter); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.STRING, bodyContents, callback, + converter); + } + + @Override + public Future executeAsync(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents, OAuthAsyncRequestCallback callback, OAuthRequest.ResponseConverter converter) { + return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.FILE, bodyContents, callback, + converter); + } + + private Future doExecuteAsync(String userAgent, Map headers, Verb httpVerb, + String completeUrl, BodyType bodyType, Object bodyContents, OAuthAsyncRequestCallback callback, + OAuthRequest.ResponseConverter converter) { + final Call call = createCall(userAgent, headers, httpVerb, completeUrl, bodyType, bodyContents); + final OkHttpFuture okHttpFuture = new OkHttpFuture<>(call); + call.enqueue(new OAuthAsyncCompletionHandler<>(callback, converter, okHttpFuture)); + return okHttpFuture; + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + byte[] bodyContents) throws InterruptedException, ExecutionException, IOException { + return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.BYTE_ARRAY, bodyContents); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + String bodyContents) throws InterruptedException, ExecutionException, IOException { + return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.STRING, bodyContents); + } + + @Override + public Response execute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + File bodyContents) throws InterruptedException, ExecutionException, IOException { + return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.FILE, bodyContents); + } + + private Response doExecute(String userAgent, Map headers, Verb httpVerb, String completeUrl, + BodyType bodyType, Object bodyContents) throws IOException { + final Call call = createCall(userAgent, headers, httpVerb, completeUrl, bodyType, bodyContents); + return convertResponse(call.execute()); + } + + private Call createCall(String userAgent, Map headers, Verb httpVerb, String completeUrl, + BodyType bodyType, Object bodyContents) { + final Request.Builder requestBuilder = new Request.Builder(); + requestBuilder.url(completeUrl); + + final String method = httpVerb.name(); + + // prepare body + final RequestBody body; + if (bodyContents != null && HttpMethod.permitsRequestBody(method)) { + final MediaType mediaType = headers.containsKey(CONTENT_TYPE) ? MediaType.parse(headers.get(CONTENT_TYPE)) + : DEFAULT_CONTENT_TYPE_MEDIA_TYPE; + + body = bodyType.createBody(mediaType, bodyContents); + } else { + body = null; + } + + // fill HTTP method and body + requestBuilder.method(method, body); + + // fill headers + for (Map.Entry header : headers.entrySet()) { + requestBuilder.addHeader(header.getKey(), header.getValue()); + } + if (userAgent != null) { + requestBuilder.header(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent); + } + + // create a new call + return client.newCall(requestBuilder.build()); + } + + private enum BodyType { + BYTE_ARRAY { + @Override + RequestBody createBody(MediaType mediaType, Object bodyContents) { + return RequestBody.create(mediaType, (byte[]) bodyContents); + } + }, + STRING { + @Override + RequestBody createBody(MediaType mediaType, Object bodyContents) { + return RequestBody.create(mediaType, (String) bodyContents); + } + }, + FILE { + @Override + RequestBody createBody(MediaType mediaType, Object bodyContents) { + return RequestBody.create(mediaType, (File) bodyContents); + } + }; + + abstract RequestBody createBody(MediaType mediaType, Object bodyContents); + } + + static Response convertResponse(okhttp3.Response okHttpResponse) { + final Headers headers = okHttpResponse.headers(); + final Map headersMap = new HashMap<>(); + + for (String name : headers.names()) { + headersMap.put(name, headers.get(name)); + } + + final ResponseBody body = okHttpResponse.body(); + return new Response(okHttpResponse.code(), okHttpResponse.message(), headersMap, + body == null ? null : body.byteStream()); + + } +} diff --git a/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpHttpClientConfig.java b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpHttpClientConfig.java new file mode 100644 index 000000000..7759a0936 --- /dev/null +++ b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpHttpClientConfig.java @@ -0,0 +1,26 @@ +package com.github.scribejava.httpclient.okhttp; + +import com.github.scribejava.core.httpclient.HttpClientConfig; +import okhttp3.OkHttpClient; + +public class OkHttpHttpClientConfig implements HttpClientConfig { + + private final OkHttpClient.Builder clientBuilder; + + public OkHttpHttpClientConfig(OkHttpClient.Builder clientBuilder) { + this.clientBuilder = clientBuilder; + } + + public OkHttpClient.Builder getClientBuilder() { + return clientBuilder; + } + + @Override + public OkHttpHttpClientConfig createDefaultConfig() { + return defaultConfig(); + } + + public static OkHttpHttpClientConfig defaultConfig() { + return new OkHttpHttpClientConfig(null); + } +} diff --git a/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpProvider.java b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpProvider.java new file mode 100644 index 000000000..4d27f5f0c --- /dev/null +++ b/scribejava-httpclient-okhttp/src/main/java/com/github/scribejava/httpclient/okhttp/OkHttpProvider.java @@ -0,0 +1,16 @@ +package com.github.scribejava.httpclient.okhttp; + +import com.github.scribejava.core.httpclient.HttpClientProvider; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.HttpClientConfig; + +public class OkHttpProvider implements HttpClientProvider { + + @Override + public HttpClient createClient(HttpClientConfig config) { + if (config instanceof OkHttpHttpClientConfig) { + return new OkHttpHttpClient((OkHttpHttpClientConfig) config); + } + return null; + } +} diff --git a/scribejava-httpclient-okhttp/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider b/scribejava-httpclient-okhttp/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider new file mode 100644 index 000000000..46afa18ed --- /dev/null +++ b/scribejava-httpclient-okhttp/src/main/resources/META-INF/services/com.github.scribejava.core.httpclient.HttpClientProvider @@ -0,0 +1 @@ +com.github.scribejava.httpclient.okhttp.OkHttpProvider diff --git a/scribejava-httpclient-okhttp/src/test/java/com/github/scribejava/httpclient/okhttp/OkHttpHttpClientTest.java b/scribejava-httpclient-okhttp/src/test/java/com/github/scribejava/httpclient/okhttp/OkHttpHttpClientTest.java new file mode 100644 index 000000000..496882cdd --- /dev/null +++ b/scribejava-httpclient-okhttp/src/test/java/com/github/scribejava/httpclient/okhttp/OkHttpHttpClientTest.java @@ -0,0 +1,112 @@ +package com.github.scribejava.httpclient.okhttp; + +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.model.OAuthConfig; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import com.github.scribejava.core.oauth.OAuth20Service; +import com.github.scribejava.core.oauth.OAuthService; +import com.github.scribejava.core.utils.StreamUtils; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; + +public class OkHttpHttpClientTest { + private OAuthService oAuthService; + + @Before + public void setUp() { + final HttpClient client = new OkHttpHttpClient(new OkHttpClient()); + oAuthService = new OAuth20Service(null, + new OAuthConfig("test", "test", null, null, null, null, null, null, null, client)); + } + + + @Test + public void shouldSendGetRequest() throws Exception { + final String expectedResponseBody = "response body"; + + final MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setBody(expectedResponseBody)); + server.start(); + + final HttpUrl baseUrl = server.url("/testUrl"); + + final OAuthRequest request = new OAuthRequest(Verb.GET, baseUrl.toString()); + final Response response = oAuthService.execute(request, null).get(30, TimeUnit.SECONDS); + + assertEquals(expectedResponseBody, response.getBody()); + + final RecordedRequest recordedRequest = server.takeRequest(); + assertEquals("GET", recordedRequest.getMethod()); + + server.shutdown(); + } + + @Test + public void shouldSendPostRequest() throws Exception { + final String expectedResponseBody = "response body"; + final String expectedRequestBody = "request body"; + + final MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setBody(expectedResponseBody)); + server.enqueue(new MockResponse().setBody(expectedResponseBody)); + server.start(); + + final HttpUrl baseUrl = server.url("/testUrl"); + + // request with body + OAuthRequest request = new OAuthRequest(Verb.POST, baseUrl.toString()); + request.setPayload(expectedRequestBody); + Response response = oAuthService.execute(request, null).get(30, TimeUnit.SECONDS); + + assertEquals(expectedResponseBody, response.getBody()); + + RecordedRequest recordedRequest = server.takeRequest(); + assertEquals("POST", recordedRequest.getMethod()); + assertEquals(expectedRequestBody, recordedRequest.getBody().readUtf8()); + + + // request with empty body + request = new OAuthRequest(Verb.POST, baseUrl.toString()); + response = oAuthService.execute(request, null).get(30, TimeUnit.SECONDS); + + assertEquals(expectedResponseBody, response.getBody()); + + recordedRequest = server.takeRequest(); + assertEquals("POST", recordedRequest.getMethod()); + assertEquals("", recordedRequest.getBody().readUtf8()); + + server.shutdown(); + } + + @Test + public void shouldReadResponseStream() throws Exception { + final String expectedResponseBody = "response body"; + + final MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setBody(expectedResponseBody)); + server.start(); + + final HttpUrl baseUrl = server.url("/testUrl"); + + final OAuthRequest request = new OAuthRequest(Verb.GET, baseUrl.toString()); + final Response response = oAuthService.execute(request, null).get(30, TimeUnit.SECONDS); + + assertEquals(expectedResponseBody, StreamUtils.getStreamContents(response.getStream())); + + final RecordedRequest recordedRequest = server.takeRequest(); + assertEquals("GET", recordedRequest.getMethod()); + + server.shutdown(); + } +}