From 5c2c48b925bb0bc0f45f5905fc68e0cc1305e631 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Tue, 11 Jul 2017 20:42:56 +0530 Subject: [PATCH 1/8] Added Frappe.io OAuth2 API --- .../com/github/scribejava/apis/FrappeApi.java | 58 +++++++++++++++ .../apis/frappe/FrappeJsonTokenExtractor.java | 31 ++++++++ .../scribejava/apis/frappe/FrappeToken.java | 70 +++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java create mode 100644 scribejava-apis/src/main/java/com/github/scribejava/apis/frappe/FrappeJsonTokenExtractor.java create mode 100644 scribejava-apis/src/main/java/com/github/scribejava/apis/frappe/FrappeToken.java diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java new file mode 100644 index 000000000..fe7e38996 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java @@ -0,0 +1,58 @@ +package com.github.scribejava.apis; + +import com.github.scribejava.core.builder.api.DefaultApi20; +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.model.Response; +import com.github.scribejava.core.model.Verb; + +import java.io.IOException; + +public class FrappeApi extends DefaultApi20 { + + String SERVER_URL = "https://erpnext.org"; + + protected FrappeApi() { + } + + private static class InstanceHolder { + private static final FrappeApi INSTANCE = new FrappeApi(); + } + + public static FrappeApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public Verb getAccessTokenVerb() { + return Verb.POST; + } + + @Override + public String getAccessTokenEndpoint() { + return this.SERVER_URL + "/api/method/frappe.integrations.oauth2.get_token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return this.SERVER_URL + "/api/method/frappe.integrations.oauth2.authorize"; + } + + @Override + public TokenExtractor getAccessTokenExtractor() { + return new TokenExtractor() { + @Override + public OAuth2AccessToken extract(Response response) throws IOException, OAuthException { + String token = null; + try { + JSONObject bearerToken = new JSONObject(response.getBody()); + token = bearerToken.getString("access_token"); + } catch (JSONException e) { + e.printStackTrace(); + } + return new OAuth2AccessToken(token); + } + }; + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/frappe/FrappeJsonTokenExtractor.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/frappe/FrappeJsonTokenExtractor.java new file mode 100644 index 000000000..ddf7fe9c8 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/frappe/FrappeJsonTokenExtractor.java @@ -0,0 +1,31 @@ +package com.github.scribejava.apis.frappe; + +import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; +import java.util.regex.Pattern; + +/** + * additionally parses OpenID id_token + */ +public class FrappeJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor { + + private static final Pattern ID_TOKEN_REGEX_PATTERN = Pattern.compile("\"id_token\"\\s*:\\s*\"(\\S*?)\""); + + protected FrappeJsonTokenExtractor() { + } + + private static class InstanceHolder { + + private static final FrappeJsonTokenExtractor INSTANCE = new FrappeJsonTokenExtractor(); + } + + public static FrappeJsonTokenExtractor instance() { + return InstanceHolder.INSTANCE; + } + + @Override + protected FrappeToken createToken(String accessToken, String tokenType, Integer expiresIn, + String refreshToken, String scope, String response) { + return new FrappeToken(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/frappe/FrappeToken.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/frappe/FrappeToken.java new file mode 100644 index 000000000..cc2776d87 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/frappe/FrappeToken.java @@ -0,0 +1,70 @@ +package com.github.scribejava.apis.frappe; + +import com.github.scribejava.core.model.OAuth2AccessToken; +import java.util.Objects; + +public class FrappeToken extends OAuth2AccessToken { + + private static final long serialVersionUID = 7845679917727899612L; + + /** + * Id_token is part of OpenID Connect specification. It can hold user information that you can directly extract + * without additional request to provider. + * + * See http://openid.net/specs/openid-connect-core-1_0.html#id_token-tokenExample and + * https://bitbucket.org/nimbusds/nimbus-jose-jwt/wiki/Home + * + * Here will be encoded and signed id token in JWT format or null, if not defined. + */ + private final String openIdToken; + + public FrappeToken(String accessToken, String openIdToken, String rawResponse) { + this(accessToken, null, null, null, null, openIdToken, rawResponse); + } + + public FrappeToken(String accessToken, String tokenType, Integer expiresIn, String refreshToken, String scope, + String openIdToken, String rawResponse) { + super(accessToken, tokenType, expiresIn, refreshToken, scope, rawResponse); + this.openIdToken = openIdToken; + } + + public String getOpenIdToken() { + return openIdToken; + } + + @Override + public int hashCode() { + int hash = super.hashCode(); + hash = 37 * hash + Objects.hashCode(openIdToken); + 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(openIdToken, ((FrappeToken) obj).getOpenIdToken()); + } + + @Override + public String toString() { + return "FrappeToken{" + + "access_token=" + getAccessToken() + + ", token_type=" + getTokenType() + + ", expires_in=" + getExpiresIn() + + ", refresh_token=" + getRefreshToken() + + ", scope=" + getScope() + + ", open_id_token=" + openIdToken + '}'; + } +} From daec2aca0cdc86c409d59af3e65d3392e07b8536 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Tue, 11 Jul 2017 21:29:53 +0530 Subject: [PATCH 2/8] [Fix] using regex to get Frappe access_token --- .../java/com/github/scribejava/apis/FrappeApi.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java index fe7e38996..e335f8814 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java @@ -41,18 +41,6 @@ protected String getAuthorizationBaseUrl() { @Override public TokenExtractor getAccessTokenExtractor() { - return new TokenExtractor() { - @Override - public OAuth2AccessToken extract(Response response) throws IOException, OAuthException { - String token = null; - try { - JSONObject bearerToken = new JSONObject(response.getBody()); - token = bearerToken.getString("access_token"); - } catch (JSONException e) { - e.printStackTrace(); - } - return new OAuth2AccessToken(token); - } - }; + return FrappeJsonTokenExtractor.instance(); } } From a4673f96619ac03e962f502ff87bc08e5f5e3c38 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Tue, 11 Jul 2017 21:40:35 +0530 Subject: [PATCH 3/8] [Fix] FrappeApi - Removed unused imports and SERVER_URL changed to serverURL --- .../java/com/github/scribejava/apis/FrappeApi.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java index e335f8814..323139bbf 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java @@ -1,17 +1,13 @@ package com.github.scribejava.apis; import com.github.scribejava.core.builder.api.DefaultApi20; -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.model.Response; import com.github.scribejava.core.model.Verb; -import java.io.IOException; - public class FrappeApi extends DefaultApi20 { - String SERVER_URL = "https://erpnext.org"; + String serverURL = "https://erpnext.org"; protected FrappeApi() { } @@ -31,12 +27,12 @@ public Verb getAccessTokenVerb() { @Override public String getAccessTokenEndpoint() { - return this.SERVER_URL + "/api/method/frappe.integrations.oauth2.get_token"; + return this.serverURL + "/api/method/frappe.integrations.oauth2.get_token"; } @Override protected String getAuthorizationBaseUrl() { - return this.SERVER_URL + "/api/method/frappe.integrations.oauth2.authorize"; + return this.serverURL + "/api/method/frappe.integrations.oauth2.authorize"; } @Override From 91914cfb8bbdb21b720c8ffa751f8e5ea3394280 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Tue, 11 Jul 2017 21:55:16 +0530 Subject: [PATCH 4/8] [Fix] FrappeApi private variable and accessor --- .../java/com/github/scribejava/apis/FrappeApi.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java index 323139bbf..55cf38a4e 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java @@ -7,7 +7,7 @@ public class FrappeApi extends DefaultApi20 { - String serverURL = "https://erpnext.org"; + private String serverURL = "https://erpnext.org"; protected FrappeApi() { } @@ -20,6 +20,14 @@ public static FrappeApi instance() { return InstanceHolder.INSTANCE; } + public String getServerURL() { + return this.serverURL; + } + + public void setServerURL(String serverURL) { + this.serverURL = serverURL; + } + @Override public Verb getAccessTokenVerb() { return Verb.POST; From 6978dc1bb7afad24086c9795b9e2b0f80c0a6f88 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Tue, 11 Jul 2017 22:01:15 +0530 Subject: [PATCH 5/8] [Fix] FrappeApi import FrappeJsonTokenExtractor --- .../src/main/java/com/github/scribejava/apis/FrappeApi.java | 1 + 1 file changed, 1 insertion(+) diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java index 55cf38a4e..62828f4cd 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java @@ -1,5 +1,6 @@ package com.github.scribejava.apis; +import com.github.scribejava.apis.frappe.FrappeJsonTokenExtractor; import com.github.scribejava.core.builder.api.DefaultApi20; import com.github.scribejava.core.extractors.TokenExtractor; import com.github.scribejava.core.model.OAuth2AccessToken; From 78d517906f43f29615470ecf4f66db3bef04fc51 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Wed, 12 Jul 2017 17:40:30 +0530 Subject: [PATCH 6/8] Added Frappe20Example.java --- .../com/github/scribejava/apis/FrappeApi.java | 7 +- .../apis/examples/Frappe20Example.java | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Frappe20Example.java diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java index 62828f4cd..e684f9ed6 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java @@ -8,7 +8,7 @@ public class FrappeApi extends DefaultApi20 { - private String serverURL = "https://erpnext.org"; + private String serverURL = "https://scribejava.mntechnique.com"; protected FrappeApi() { } @@ -29,11 +29,6 @@ public void setServerURL(String serverURL) { this.serverURL = serverURL; } - @Override - public Verb getAccessTokenVerb() { - return Verb.POST; - } - @Override public String getAccessTokenEndpoint() { return this.serverURL + "/api/method/frappe.integrations.oauth2.get_token"; diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Frappe20Example.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Frappe20Example.java new file mode 100644 index 000000000..be6b7d730 --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Frappe20Example.java @@ -0,0 +1,68 @@ +package com.github.scribejava.apis.examples; + +import java.util.Scanner; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.apis.FrappeApi; +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 Frappe20Example { + + private static final String NETWORK_NAME = "Frappe"; + private static final String PROTECTED_RESOURCE_URL = "https://scribejava.mntechnique.com/api/method/frappe.integrations.oauth2.openid_profile"; + + private Frappe20Example() { + } + + public static void main(String... args) throws IOException, InterruptedException, ExecutionException { + //Replace these with your client id and secret + final String clientId = "37763ecdb0"; + final String clientSecret = "3e1d716ea7"; + final OAuth20Service service = new ServiceBuilder(clientId) + .apiSecret(clientSecret) + .scope("openid all") + .callback("https://example.com/callback") + .build(FrappeApi.instance()); + final Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("=== " + NETWORK_NAME + "'s OAuth 2.0 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 Authorization Code 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! :)"); + } +} From 4e831b8918a9f37c4c609be0b85a8d00a760eb54 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Wed, 12 Jul 2017 17:50:37 +0530 Subject: [PATCH 7/8] [Fix] removed unused import Verb --- .../src/main/java/com/github/scribejava/apis/FrappeApi.java | 1 - 1 file changed, 1 deletion(-) diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java index e684f9ed6..b0151cb7f 100644 --- a/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/FrappeApi.java @@ -4,7 +4,6 @@ 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; public class FrappeApi extends DefaultApi20 { From 2744d91fef36f5d5bf96e96b85e5c7cc304559d4 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Wed, 12 Jul 2017 17:53:51 +0530 Subject: [PATCH 8/8] [Fix] Split line to make it under 120 chars --- .../com/github/scribejava/apis/examples/Frappe20Example.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Frappe20Example.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Frappe20Example.java index be6b7d730..25e0f4e79 100644 --- a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Frappe20Example.java +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Frappe20Example.java @@ -14,7 +14,8 @@ public final class Frappe20Example { private static final String NETWORK_NAME = "Frappe"; - private static final String PROTECTED_RESOURCE_URL = "https://scribejava.mntechnique.com/api/method/frappe.integrations.oauth2.openid_profile"; + private static final String PROTECTED_RESOURCE_URL = "https://scribejava.mntechnique.com/" + + "api/method/frappe.integrations.oauth2.openid_profile"; private Frappe20Example() { }