com.github.scribejava.apis.SalesforceApi Maven / Gradle / Ivy
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 com.github.scribejava.core.oauth2.clientauthentication.ClientAuthentication;
import com.github.scribejava.core.oauth2.clientauthentication.RequestBodyAuthenticationScheme;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
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 (protocol.startsWith("TLSv1.")) {
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 or higher
* @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;
}
final String[] supportedProtocols = socket.getSupportedProtocols();
Arrays.sort(supportedProtocols);
for (int i = supportedProtocols.length - 1; i >= 0; i--) {
final String supportedProtocol = supportedProtocols[i];
if (supportedProtocol.startsWith("TLSv1.")) {
final SSLContext context = SSLContext.getInstance(supportedProtocol);
context.init(null, null, null);
SSLContext.setDefault(context);
return;
}
}
throw new NoSuchAlgorithmException("for Salesforce API to work you need jvm with TLS 1.1 or higher support");
}
@Override
public ClientAuthentication getClientAuthentication() {
return RequestBodyAuthenticationScheme.instance();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy