Skip to content
This repository has been archived by the owner on Jan 19, 2024. It is now read-only.

Commit

Permalink
Refresh token public app support (#108)
Browse files Browse the repository at this point in the history
* Removed commented lines of code from ETClientTest.java

* Started implementing RefreshToken, Public and Web App support for OAuth2.0

* Finished implementing the support for RefreshToken, Public/Web App

* Fixed a bug

* Refactored the name of the input parameter of the isNullOrBlankOrEmpty function

* Minor refactor in ETClient.java

Extracted the multiple usages of configuration.get(applicationType) into a variable
  • Loading branch information
sfcbetiuc authored and manivinesh committed Aug 21, 2019
1 parent 1062511 commit f6b7ad9
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 133 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,32 @@ Java platform. Among other things, the SDK:
For more information about the Java SDK and how to use it, please see
the Javadocs at http://salesforce-marketingcloud.github.io/FuelSDK-Java/.

New Features in Version 1.5.0
------------
* Added Refresh Token support for OAuth2 authentication
* Added Web/Public App support for OAuth2 authentication

More details on Access Tokens for Web/Public Apps can be found [here](https://developer.salesforce.com/docs/atlas.en-us.mc-app-development.meta/mc-app-development/access-token-app.htm)

Sample Config for OAuth2:

```
clientId=<CLIENT_ID>
clientSecret=<CLIENT_SECRET>
authEndpoint=<AUTH TENANT SPECIFIC ENDPOINT>
endpoint=<REST TENANT SPECIFIC ENDPOINT>
soapEndpoint=<SOAP TENANT SPECIFIC ENDPOINT>
useOAuth2Authentication=true
accountId=<TARGET_ACCOUNT_ID>
scope=<PERMISSION_LIST>
applicationType=<APPLICATION_TYPE>
redirectURI=<REDIRECT_URI_FOR_PUBLIC/WEB_APP>
authorizationCode=<AUTHORIZATION_CODE_FOR_PUBLIC/WEB_APP>
```

* applicationType can have one of the following values: `server`, `public`, `web`. The default value of applicationType is `server`.


New Features in Version 1.4.0
------------
* Added support for OAuth2 authentication - [More Details](https://developer.salesforce.com/docs/atlas.en-us.mc-app-development.meta/mc-app-development/integration-considerations.htm)
Expand All @@ -51,7 +77,7 @@ The easiest way to install the Java SDK is via Maven&mdash;simply add the follow
<dependency>
<groupId>com.github.salesforce-marketingcloud</groupId>
<artifactId>fuelsdk</artifactId>
<version>1.4.0</version>
<version>1.5.0</version>
</dependency>

Maven will automatically resolve, download, and install all dependencies for you.
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.salesforce-marketingcloud</groupId>
<artifactId>fuelsdk</artifactId>
<version>1.4.0</version>
<version>1.5.0</version>
<name>Salesforce Marketing Cloud Java SDK</name>
<description>Salesforce Marketing Cloud Java SDK</description>
<url>https://github.com/salesforce-marketingcloud/FuelSDK-Java</url>
Expand Down
167 changes: 96 additions & 71 deletions src/main/java/com/exacttarget/fuelsdk/ETClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
Expand Down Expand Up @@ -78,9 +79,6 @@ public class ETClient {
private String clientId = null;
private String clientSecret = null;

private String username = null;
private String password = null;

private String endpoint = null;
private String authEndpoint = null;
private String soapEndpoint = null;
Expand All @@ -96,17 +94,28 @@ public class ETClient {
private String accessToken = null;
private int expiresIn = 0;
private String legacyToken = null;

public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}

public String getRefreshToken() {
return refreshToken;
}

private String refreshToken = null;

private long tokenExpirationTime = 0;
private static long soapEndpointExpiration = 0;
private static String fetchedSoapEndpoint = null;
private static final long cacheDurationInMillis = 1000 * 60 * 10; // 10 minutes
private boolean useOAuth2Authentication;
private String accountId;
private String scope;

/**
private String applicationType;
private String authorizationCode;
private String redirectURI;

/**
* Class constructor, Initializes a new instance of the class.
*/
public ETClient()
Expand Down Expand Up @@ -137,9 +146,6 @@ public ETClient(ETConfiguration configuration)
clientId = configuration.get("clientId");
clientSecret = configuration.get("clientSecret");

username = configuration.get("username");
password = configuration.get("password");

endpoint = configuration.get("endpoint");
if (endpoint == null) {
endpoint = DEFAULT_ENDPOINT;
Expand All @@ -159,30 +165,37 @@ public ETClient(ETConfiguration configuration)
gson = gsonBuilder.create();
}

useOAuth2Authentication = configuration.isTrue("useOAuth2Authentication") ? true : false;
accountId = configuration.get("accountId");
scope = configuration.get("scope");
useOAuth2Authentication = configuration.isTrue("useOAuth2Authentication");

if (clientId != null && clientSecret != null) {
authConnection = new ETRestConnection(this, authEndpoint, true);
requestToken();
restConnection = new ETRestConnection(this, endpoint);
fetchSoapEndpoint();
soapConnection = new ETSoapConnection(this, soapEndpoint, accessToken);
} else {
if (username == null || password == null) {
throw new ETSdkException("must specify either " +
"clientId/clientSecret or username/password");
applicationType = configuration.get("applicationType");
authorizationCode = configuration.get("authorizationCode");
redirectURI = configuration.get("redirectURI");

if(isNullOrBlankOrEmpty(applicationType)){
applicationType = "server";
configuration.set("applicationType", "server");
}

if(applicationType.equals("public") || applicationType.equals("web")){
if (isNullOrBlankOrEmpty(authorizationCode) || isNullOrBlankOrEmpty(redirectURI)){
throw new ETSdkException("AuthorizationCode or RedirectURI is null: For Public/Web Apps, " +
"authorizationCode and redirectURI must be provided in config file");
}
if (soapEndpoint == null) {
throw new ETSdkException("must specify soapEndpoint " +
"when authenticating with username/password");
}

if(applicationType.equals("public")){
if(isNullOrBlankOrEmpty(clientId)){
throw new ETSdkException("ClientId is null: clientId must be provided in config file");
}
}
else{
if(isNullOrBlankOrEmpty(clientId) || isNullOrBlankOrEmpty(clientSecret)){
throw new ETSdkException("ClientId or ClientSecret is null: clientId and clientSecret must be provided in config file");
}
soapConnection = new ETSoapConnection(this, soapEndpoint,
username,
password);
}

buildClients();

if (configuration.isFalse("autoHydrateObjects")) {
autoHydrateObjects = false;
}
Expand All @@ -191,15 +204,25 @@ public ETClient(ETConfiguration configuration)
logger.trace("ETClient initialized:");
logger.trace(" clientId = " + clientId);
logger.trace(" clientSecret = *");
logger.trace(" username = " + username);
logger.trace(" password = *");
logger.trace(" endpoint = " + endpoint);
logger.trace(" authEndpoint = " + authEndpoint);
logger.trace(" soapEndpoint = " + soapEndpoint);
logger.trace(" autoHydrateObjects = " + autoHydrateObjects);
}
}

private void buildClients() throws ETSdkException {
authConnection = new ETRestConnection(this, authEndpoint, true);
requestToken();
restConnection = new ETRestConnection(this, endpoint);
fetchSoapEndpoint();
soapConnection = new ETSoapConnection(this, soapEndpoint, accessToken);
}

public static boolean isNullOrBlankOrEmpty(String str) {
return str == null || StringUtils.isBlank(str) || StringUtils.isEmpty(str);
}

private void fetchSoapEndpoint() {
if(useOAuth2Authentication) {
return;
Expand Down Expand Up @@ -329,32 +352,8 @@ public synchronized String requestToken()
private synchronized String requestOAuth2Token()
throws ETSdkException
{
if (clientId == null || clientSecret == null) {
// no-op
return null;
}
//
// Construct the JSON payload.
//

JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("client_id", clientId);
jsonObject.addProperty("client_secret", clientSecret);
jsonObject.addProperty("grant_type", "client_credentials");
if(accountId != null && accountId.length() > 0)
{
jsonObject.addProperty("account_id", accountId);
}
if(scope != null && scope.length() > 0)
{
jsonObject.addProperty("scope", scope);
}

String requestPayload = gson.toJson(jsonObject);

ETRestConnection.Response response = null;

response = authConnection.post(PATH_OAUTH2TOKEN, requestPayload);
JsonObject payload = createPayload(configuration);
ETRestConnection.Response response = authConnection.post(PATH_OAUTH2TOKEN, gson.toJson(payload));

if (response.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new ETSdkException("error obtaining OAuth2 access token "
Expand All @@ -364,34 +363,60 @@ private synchronized String requestOAuth2Token()
+ response.getResponseMessage()
+ ")");
}

//
// Parse the JSON response into the appropriate instance
// variables:
//
JsonParser jsonParser = new JsonParser();

String responsePayload = response.getResponsePayload();
JsonObject jsonObject = jsonParser.parse(responsePayload).getAsJsonObject();

JsonParser jsonParser = new JsonParser();
jsonObject = jsonParser.parse(responsePayload).getAsJsonObject();
this.accessToken = jsonObject.get("access_token").getAsString();
this.expiresIn = jsonObject.get("expires_in").getAsInt();
this.endpoint = jsonObject.get("rest_instance_url").getAsString();
this.soapEndpoint = jsonObject.get("soap_instance_url").getAsString() + "service.asmx";

//
// Calculate the token expiration time. As before,
// System.currentTimeMills() is in milliseconds so
// we multiply expiresIn by 1000:
//

this.expiresIn = jsonObject.get("expires_in").getAsInt();
tokenExpirationTime = System.currentTimeMillis() + (expiresIn * 1000);

if(jsonObject.has("refresh_token")){
this.refreshToken = jsonObject.get("refresh_token").getAsString();
}

return accessToken;
}

JsonObject createPayload(ETConfiguration configuration) {
JsonObject payload = new JsonObject();

payload.addProperty("client_id", configuration.get("clientId"));

String applicationType = configuration.get("applicationType");

if(applicationType.equals("web") || applicationType.equals("server")){
payload.addProperty("client_secret", configuration.get("clientSecret"));
}
if(!isNullOrBlankOrEmpty(refreshToken)){
payload.addProperty("grant_type", "refresh_token");
payload.addProperty("refresh_token", refreshToken);
}
else if(applicationType.equals("public") || applicationType.equals("web")){
payload.addProperty("grant_type", "authorization_code");
payload.addProperty("code", configuration.get("authorizationCode"));
payload.addProperty("redirect_uri", configuration.get("redirectURI"));
}
else{
payload.addProperty("grant_type", "client_credentials");
}

if(!isNullOrBlankOrEmpty(configuration.get("accountId"))){
payload.addProperty("account_id", configuration.get("accountId"));
}
if(!isNullOrBlankOrEmpty(configuration.get("scope"))){
payload.addProperty("scope", configuration.get("scope"));
}

return payload;
}

/**
*
*
* @param refreshToken The refresh token
* @return The request token
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ private HttpURLConnection sendRequest(URL url, Method method, String payload)
try {
connection = (HttpURLConnection) url.openConnection();

connection.setRequestProperty("User-Agent", "FuelSDK-Java-v1.4.0-REST-"+method+"-"+object);
connection.setRequestProperty("User-Agent", "FuelSDK-Java-v1.5.0-REST-"+method+"-"+object);
connection.setRequestMethod(method.toString());
} catch (ProtocolException ex) {
throw new ETSdkException("error setting request method: " + method.toString(), ex);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/exacttarget/fuelsdk/ETSoapConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,12 @@ public Soap getSoap() {
}

public Soap getSoap(String m) {
soapClient.getRequestContext().put("HTTP_HEADER_USER_AGENT", "FuelSDK-Java-v1.4.0-SOAP-"+m);
soapClient.getRequestContext().put("HTTP_HEADER_USER_AGENT", "FuelSDK-Java-v1.5.0-SOAP-"+m);
return soap;
}

public Soap getSoap(String m, String o) {
soapClient.getRequestContext().put("HTTP_HEADER_USER_AGENT", "FuelSDK-Java-v1.4.0-SOAP-"+m+"-"+o);
soapClient.getRequestContext().put("HTTP_HEADER_USER_AGENT", "FuelSDK-Java-v1.5.0-SOAP-"+m+"-"+o);
return soap;
}

Expand Down
Loading

0 comments on commit f6b7ad9

Please sign in to comment.