GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Add Salesforce API · crazycode/scribejava@821bc7c

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • README.md
  • changelog
  • scribejava-apis/src
    • main/java/com/github/scribejava/apis
      • SalesforceApi.java
      • google
        • GoogleJsonTokenExtractor.java
        • GoogleToken.java
      • salesforce
        • SalesforceJsonTokenExtractor.java
        • SalesforceToken.java
    • test/java/com/github/scribejava/apis/examples
      • SalesforceExample.java
      • SalesforceNingAsyncExample.java
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎README.md‎

Copy file name to clipboardExpand all lines: README.md
+1Lines changed: 1 addition & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ You can use ning async http client out-of-box, just use ServiceBuilderAsync
4747
* Pinterest (https://www.pinterest.com/)
4848
* 500px (https://500px.com/)
4949
* Renren (http://renren.com/)
50+
* Salesforce (https://www.salesforce.com/)
5051
* Sina (http://www.sina.com.cn/ http://weibo.com/login.php)
5152
* Skyrock (http://skyrock.com/)
5253
* sohu 搜狐 (http://www.sohu.com/)
Collapse file

‎changelog‎

Copy file name to clipboardExpand all lines: changelog
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
[SNAPSHOT]
2+
* add Salesforce API
3+
14
[2.7.3]
25
* FIX: ScribeJava shouldn't require all async http client provider to be on the classpath if using only one of them
36

Collapse file

‎scribejava-apis/src/main/java/com/github/scribejava/apis/SalesforceApi.java‎

Copy file name to clipboard
+115Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package com.github.scribejava.apis;
2+
3+
import javax.net.ssl.SSLContext;
4+
5+
import com.github.scribejava.apis.salesforce.SalesforceJsonTokenExtractor;
6+
import com.github.scribejava.core.builder.api.DefaultApi20;
7+
import com.github.scribejava.core.extractors.TokenExtractor;
8+
import com.github.scribejava.core.model.OAuth2AccessToken;
9+
import com.github.scribejava.core.model.Verb;
10+
import java.io.IOException;
11+
import java.security.KeyManagementException;
12+
import java.security.NoSuchAlgorithmException;
13+
import javax.net.ssl.SSLSocket;
14+
15+
/**
16+
* This class is an implementation of the Salesforce OAuth2 API.
17+
*/
18+
public class SalesforceApi extends DefaultApi20 {
19+
20+
private static final String BASE_URL = "https://login.salesforce.com/services/oauth2";
21+
private static final String ACCESS_URL = BASE_URL + "/token";
22+
private static final String AUTHORIZE_URL = BASE_URL + "/authorize";
23+
24+
protected SalesforceApi() {
25+
26+
try {
27+
final SSLSocket socket = (SSLSocket) SSLContext.getDefault().getSocketFactory().createSocket();
28+
if (!isTLSv11orUpperEnabled(socket)) {
29+
throw new IllegalStateException("Salesforce API required to use TLSv1.1 or upper. "
30+
+ "Enabled it by invoking method initTLSv11orUpper or somehow else");
31+
}
32+
} catch (NoSuchAlgorithmException | IOException ex) {
33+
throw new IllegalStateException("Salesforce API required to use TLSv1.1 or upper. "
34+
+ "Enabled it by invoking method initTLSv11orUpper or somehow else");
35+
}
36+
}
37+
38+
private static class InstanceHolder {
39+
40+
private static final SalesforceApi INSTANCE = new SalesforceApi();
41+
}
42+
43+
public static SalesforceApi instance() {
44+
return InstanceHolder.INSTANCE;
45+
}
46+
47+
@Override
48+
public Verb getAccessTokenVerb() {
49+
return Verb.POST;
50+
}
51+
52+
@Override
53+
public String getAccessTokenEndpoint() {
54+
return ACCESS_URL;
55+
}
56+
57+
@Override
58+
protected String getAuthorizationBaseUrl() {
59+
return AUTHORIZE_URL;
60+
}
61+
62+
@Override
63+
public TokenExtractor<OAuth2AccessToken> getAccessTokenExtractor() {
64+
return SalesforceJsonTokenExtractor.instance();
65+
}
66+
67+
private static boolean isTLSv11orUpperEnabled(final SSLSocket socket) {
68+
for (String protocol : socket.getEnabledProtocols()) {
69+
if ("TLSv1.2".equals(protocol) || "TLSv1.1".equals(protocol)) {
70+
return true;
71+
}
72+
}
73+
return false;
74+
}
75+
76+
/**
77+
* Salesforce API required to use TLSv1.1 or upper.
78+
* <p>
79+
* Java 8 have TLS 1.2 enabled by default. java 7 - no, you should invoke this method or turn TLS&gt;=1.1 somehow
80+
* else</p>
81+
*
82+
* @throws java.security.NoSuchAlgorithmException in case your jvm doesn't support TLSv1.1 and TLSv1.2
83+
* @throws java.security.KeyManagementException
84+
* @throws java.io.IOException
85+
*/
86+
public static void initTLSv11orUpper() throws NoSuchAlgorithmException, KeyManagementException, IOException {
87+
final SSLSocket socket = (SSLSocket) SSLContext.getDefault().getSocketFactory().createSocket();
88+
if (isTLSv11orUpperEnabled(socket)) {
89+
return;
90+
}
91+
boolean supportTLSv11 = false;
92+
boolean supportTLSv12 = false;
93+
for (String protocol : socket.getSupportedProtocols()) {
94+
if ("TLSv1.2".equals(protocol)) {
95+
supportTLSv12 = true;
96+
break;
97+
}
98+
if ("TLSv1.1".equals(protocol)) {
99+
supportTLSv11 = true;
100+
}
101+
}
102+
103+
final SSLContext context;
104+
if (supportTLSv12) {
105+
context = SSLContext.getInstance("TLSv1.2");
106+
} else if (supportTLSv11) {
107+
context = SSLContext.getInstance("TLSv1.1");
108+
} else {
109+
throw new NoSuchAlgorithmException("for Salesforce API to work you need jvm with TLS 1.1 or 1.2 support");
110+
}
111+
112+
context.init(null, null, null);
113+
SSLContext.setDefault(context);
114+
}
115+
}
Collapse file

‎scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleJsonTokenExtractor.java‎

Copy file name to clipboardExpand all lines: scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleJsonTokenExtractor.java
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.github.scribejava.apis.google;
22

33
import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor;
4-
import com.github.scribejava.core.model.OAuth2AccessToken;
54

65
/**
76
* additionally parses OpenID id_token
@@ -23,7 +22,7 @@ public static GoogleJsonTokenExtractor instance() {
2322
}
2423

2524
@Override
26-
protected OAuth2AccessToken createToken(String accessToken, String tokenType, Integer expiresIn,
25+
protected GoogleToken createToken(String accessToken, String tokenType, Integer expiresIn,
2726
String refreshToken, String scope, String response) {
2827
return new GoogleToken(accessToken, tokenType, expiresIn, refreshToken, scope,
2928
extractParameter(response, ID_TOKEN_REGEX, false), response);
Collapse file

‎scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleToken.java‎

Copy file name to clipboardExpand all lines: scribejava-apis/src/main/java/com/github/scribejava/apis/google/GoogleToken.java
+4-21Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,7 @@ public String getOpenIdToken() {
3434

3535
@Override
3636
public int hashCode() {
37-
int hash = 5;
38-
hash = 37 * hash + Objects.hashCode(getAccessToken());
39-
hash = 37 * hash + Objects.hashCode(getTokenType());
40-
hash = 37 * hash + Objects.hashCode(getExpiresIn());
41-
hash = 37 * hash + Objects.hashCode(getRefreshToken());
42-
hash = 37 * hash + Objects.hashCode(getScope());
37+
int hash = super.hashCode();
4338
hash = 37 * hash + Objects.hashCode(openIdToken);
4439
return hash;
4540
}
@@ -55,23 +50,11 @@ public boolean equals(Object obj) {
5550
if (getClass() != obj.getClass()) {
5651
return false;
5752
}
58-
final GoogleToken other = (GoogleToken) obj;
59-
if (!Objects.equals(getAccessToken(), other.getAccessToken())) {
53+
if (!super.equals(obj)) {
6054
return false;
6155
}
62-
if (!Objects.equals(getTokenType(), other.getTokenType())) {
63-
return false;
64-
}
65-
if (!Objects.equals(getRefreshToken(), other.getRefreshToken())) {
66-
return false;
67-
}
68-
if (!Objects.equals(getScope(), other.getScope())) {
69-
return false;
70-
}
71-
if (!Objects.equals(openIdToken, other.getOpenIdToken())) {
72-
return false;
73-
}
74-
return Objects.equals(getExpiresIn(), other.getExpiresIn());
56+
57+
return Objects.equals(openIdToken, ((GoogleToken) obj).getOpenIdToken());
7558
}
7659

7760
@Override
Collapse file

‎scribejava-apis/src/main/java/com/github/scribejava/apis/salesforce/SalesforceJsonTokenExtractor.java‎

Copy file name to clipboard
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.github.scribejava.apis.salesforce;
2+
3+
import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor;
4+
5+
/**
6+
* This extractor parses in addition to the standard Extractor the instance_url
7+
* of the used Salesforce organization.
8+
*/
9+
public class SalesforceJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {
10+
11+
private static final String INSTANCE_URL_REGEX = "\"instance_url\"\\s*:\\s*\"(\\S*?)\"";
12+
13+
protected SalesforceJsonTokenExtractor() {
14+
}
15+
16+
private static class InstanceHolder {
17+
18+
private static final SalesforceJsonTokenExtractor INSTANCE = new SalesforceJsonTokenExtractor();
19+
}
20+
21+
public static SalesforceJsonTokenExtractor instance() {
22+
return InstanceHolder.INSTANCE;
23+
}
24+
25+
@Override
26+
protected SalesforceToken createToken(String accessToken, String tokenType, Integer expiresIn,
27+
String refreshToken, String scope, String response) {
28+
return new SalesforceToken(accessToken, tokenType, expiresIn, refreshToken, scope,
29+
extractParameter(response, INSTANCE_URL_REGEX, true), response);
30+
}
31+
}
Collapse file

‎scribejava-apis/src/main/java/com/github/scribejava/apis/salesforce/SalesforceToken.java‎

Copy file name to clipboard
+65Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.github.scribejava.apis.salesforce;
2+
3+
import java.util.Objects;
4+
5+
import com.github.scribejava.core.model.OAuth2AccessToken;
6+
7+
public class SalesforceToken extends OAuth2AccessToken {
8+
9+
private static final long serialVersionUID = 7845679917727899612L;
10+
11+
/**
12+
* This token model includes the instance_url to address the needed
13+
* Salesforce organization instance.
14+
*/
15+
private final String instanceUrl;
16+
17+
public SalesforceToken(String accessToken, String instanceUrl, String rawResponse) {
18+
this(accessToken, null, null, null, null, instanceUrl, rawResponse);
19+
}
20+
21+
public SalesforceToken(String accessToken, String tokenType, Integer expiresIn, String refreshToken, String scope,
22+
String instanceUrl, String rawResponse) {
23+
super(accessToken, tokenType, expiresIn, refreshToken, scope, rawResponse);
24+
this.instanceUrl = instanceUrl;
25+
}
26+
27+
public String getInstanceUrl() {
28+
return instanceUrl;
29+
}
30+
31+
@Override
32+
public int hashCode() {
33+
int hash = super.hashCode();
34+
hash = 37 * hash + Objects.hashCode(instanceUrl);
35+
return hash;
36+
}
37+
38+
@Override
39+
public boolean equals(Object obj) {
40+
if (this == obj) {
41+
return true;
42+
}
43+
if (obj == null) {
44+
return false;
45+
}
46+
if (getClass() != obj.getClass()) {
47+
return false;
48+
}
49+
if (!super.equals(obj)) {
50+
return false;
51+
}
52+
return Objects.equals(instanceUrl, ((SalesforceToken) obj).getInstanceUrl());
53+
}
54+
55+
@Override
56+
public String toString() {
57+
return "SalesforceToken{"
58+
+ "access_token=" + getAccessToken()
59+
+ ", token_type=" + getTokenType()
60+
+ ", expires_in=" + getExpiresIn()
61+
+ ", refresh_token=" + getRefreshToken()
62+
+ ", scope=" + getScope()
63+
+ ", instance_url=" + instanceUrl + '}';
64+
}
65+
}
Collapse file

‎scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceExample.java‎

Copy file name to clipboard
+83Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.github.scribejava.apis.examples;
2+
3+
import java.io.IOException;
4+
import java.net.URLDecoder;
5+
import java.net.URLEncoder;
6+
import java.util.Scanner;
7+
8+
import com.github.scribejava.apis.SalesforceApi;
9+
import com.github.scribejava.apis.salesforce.SalesforceToken;
10+
import com.github.scribejava.core.builder.ServiceBuilder;
11+
import com.github.scribejava.core.model.OAuthRequest;
12+
import com.github.scribejava.core.model.Response;
13+
import com.github.scribejava.core.model.Verb;
14+
import com.github.scribejava.core.oauth.OAuth20Service;
15+
import java.security.KeyManagementException;
16+
import java.security.NoSuchAlgorithmException;
17+
18+
public abstract class SalesforceExample {
19+
20+
private static final String NETWORK_NAME = "Salesforce";
21+
22+
public static void main(String... args) throws IOException, NoSuchAlgorithmException, KeyManagementException {
23+
// Replace these with your client id and secret
24+
final String clientId = "your client id";
25+
final String clientSecret = "your client secret";
26+
//IT's important! Salesforce upper require TLS v1.1 or 1.2
27+
SalesforceApi.initTLSv11orUpper();
28+
final OAuth20Service service = new ServiceBuilder()
29+
.apiKey(clientId)
30+
.apiSecret(clientSecret)
31+
.callback("https://www.example.com/callback")
32+
.build(SalesforceApi.instance());
33+
34+
System.out.println("=== " + NETWORK_NAME + "'s OAuth20 Workflow ===");
35+
System.out.println();
36+
37+
// Obtain the Authorization URL
38+
System.out.println("Fetching the Authorization URL...");
39+
final String authorizationUrl = service.getAuthorizationUrl();
40+
System.out.println("Got the Authorization URL!");
41+
System.out.println("Now go and authorize ScribeJava here:");
42+
System.out.println(authorizationUrl);
43+
System.out.println("And paste the authorization code here");
44+
System.out.print(">>");
45+
final String code;
46+
try (Scanner in = new Scanner(System.in)) {
47+
code = in.nextLine();
48+
}
49+
System.out.println();
50+
51+
// The code needs to be URL decoded
52+
final String codeEncoded = URLDecoder.decode(code, "UTF-8");
53+
54+
// Trade the Request Token and Verifier for the Access Token
55+
System.out.println("Trading the Request Token for an Access Token...");
56+
final SalesforceToken accessToken = (SalesforceToken) service.getAccessToken(codeEncoded);
57+
System.out.println("Got the Access Token!");
58+
System.out.println("(if your curious it looks like this: " + accessToken + ", 'rawResponse'='"
59+
+ accessToken.getRawResponse() + "')");
60+
System.out.println();
61+
62+
System.out.println("instance_url is: " + accessToken.getInstanceUrl());
63+
64+
// Now let's go and ask for a protected resource!
65+
System.out.println("Now we're reading accounts from the Salesforce org (maxing them to 10).");
66+
67+
// Sample SOQL statement
68+
final String queryEncoded = URLEncoder.encode("Select Id, Name from Account LIMIT 10", "UTF-8");
69+
70+
// Building the query URI. We've parsed the instance URL from the accessToken request.
71+
final String url = accessToken.getInstanceUrl() + "/services/data/v36.0/query?q=" + queryEncoded;
72+
73+
System.out.println();
74+
System.out.println("Full URL: " + url);
75+
76+
final OAuthRequest request = new OAuthRequest(Verb.GET, url, service);
77+
request.addHeader("Authorization", "Bearer " + accessToken.getAccessToken());
78+
final Response response = request.send();
79+
System.out.println();
80+
System.out.println(response.getCode());
81+
System.out.println(response.getBody());
82+
}
83+
}

0 commit comments

Comments
0 (0)
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.