Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: HTTPClient-SSL MbedJSONValue
Dependents: df-2014-salesforce-hrm-k64f
Fork of SalesforceInterface by
SalesforceInterface.cpp
- Committer:
- ansond
- Date:
- 2014-09-19
- Revision:
- 4:b5c4f05bcd9d
- Parent:
- 1:a7dca096e47d
- Child:
- 7:97ea5ef906f7
File content as of revision 4:b5c4f05bcd9d:
/* Copyright C2014 ARM, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files the "Software", to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// Tuneables
#define SF_OAUTH_TOKEN_URL "https://login.salesforce.com/services/oauth2/token"
#define SF_OAUTH_REQUEST_BODY "grant_type=password&client_id=%s&client_secret=%s&username=%s&password=%s"
#define SF_HTTP_AUTH_HEADER "Authorization: Bearer %s"
#define MAX_BUFFER_LENGTH 1024
// convenience macros
#define ALLOC_BUFFER(x) char x[MAX_BUFFER_LENGTH+1];memset(x,0,MAX_BUFFER_LENGTH+1);
// include class definition
#include "SalesforceInterface.h"
// Supported DataTypes for HTTPClient
#include "HTTPMap.h"
#include "HTTPJson.h"
// default constructor
SalesforceInterface::SalesforceInterface(ErrorHandler *logger,HTTPClient *http) {
this->m_logger = logger;
this->m_http = http;
this->m_username = NULL;
this->m_password = NULL;
this->m_client_id = NULL;
this->m_client_secret = NULL;
this->m_have_creds = false;
}
// destructor
SalesforceInterface::~SalesforceInterface() {
}
// set credentials
void SalesforceInterface::setCredentials(char *username,char *password,char *client_id,char *client_secret) {
this->m_username = NULL;
this->m_password = NULL;
this->m_client_id = NULL;
this->m_client_secret = NULL;
this->m_have_creds = false;
if (username != NULL) {
this->m_username = username;
if (password != NULL) {
this->m_password = password;
if (client_id != NULL) {
this->m_client_id = client_id;
if (client_secret != NULL) {
this->m_client_secret = client_secret;
this->m_have_creds = true;
}
}
}
}
}
// convenience accessors
ErrorHandler *SalesforceInterface::logger() { return this->m_logger; }
HTTPClient *SalesforceInterface::http() { return this->m_http; }
bool SalesforceInterface::haveCreds() { return this->m_have_creds; }
//
// get OAUTH2 Token - taken from here:
// https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com#Obtaining_a_Token_in_an_Autonomous_Client_.28Username_and_Password_Flow.29
//
char *SalesforceInterface::getOauthToken(char *output_buffer,int output_buffer_length) {
if (this->haveCreds()) {
// construct the OAUTH2 Token request body
HTTPMap input;
//
// FORMAT: Taken from URL above method signature:
//
// grant_type=password&client_id=<your_client_id>&client_secret=<your_client_secret>&username=<your_username>&password=<your_password>
//
// ContentType: application/x-www-form-urlencoded
//
input.put("grant_type","password");
input.put("client_id",this->m_client_id);
input.put("client_secret",this->m_client_secret);
input.put("username",this->m_username);
input.put("password",this->m_password);
// prepare the output buffer
HTTPText output(output_buffer,output_buffer_length);
// HTTP POST call to gett he token
DEBUG("getOauthToken: Calling %s...",SF_OAUTH_TOKEN_URL);
HTTPResult status = this->http()->post(SF_OAUTH_TOKEN_URL,input,&output);
// check the result and return the token
DEBUG("getOauthToken: status(%d) response: %s",status,output_buffer);
if (status == 0) return output_buffer;
}
else {
// no credentials
this->logger()->log("no/incomplete salesforce.com credentials provided. Unable to acquire OAUTH2 token...");
}
return NULL;
}
// Salesforce.com Invoke: defaults to GET
char *SalesforceInterface::invoke(char *url,char *output_buffer,int output_buffer_len) {
return this->invoke(url,NUM_TYPES,NULL,0,output_buffer,output_buffer_len,GET);
}
// Salesforce.com Invoke: defaults to POST with JSON input data type
char *SalesforceInterface::invoke(char *url,char *input_data,int input_data_len,char *output_buffer,int output_buffer_len) {
return this->invoke(url,JSON,input_data,input_data_len,output_buffer,output_buffer_len);
}
// Salesforce.com Invoke: defaults to POST with variable input data type
char *SalesforceInterface::invoke(char *url,InputDataTypes input_type,char *input_data,int input_data_len,char *output_buffer,int output_buffer_len) {
return this->invoke(url,input_type,input_data,input_data_len,output_buffer,output_buffer_len,POST);
}
// Salesforce.com Invoke: full fidelity method
char *SalesforceInterface::invoke(char *url,InputDataTypes input_type,char *input_data,int input_data_len,char *output_buffer,int output_buffer_len,HttpVerb verb) {
// initialize our invocation status
HTTPResult status = HTTP_ERROR;
if (this->haveCreds() && output_buffer != NULL && output_buffer_len > 0) {
// first we have to get our OAUTH2 Token
ALLOC_BUFFER(token_buffer);
// get the OAUTH2 token
char *token = this->getOauthToken(token_buffer,sizeof(token_buffer));
if (token != NULL) {
// Parse the OAUTH2 token
MbedJSONValue parsed_token;
parse(parsed_token,token);
// extract the OAUTH2 token
string access_token = parsed_token["access_token"].get<std::string>();
// DEBUG
this->logger()->log("OAUTH: %s",access_token.c_str());
// use OAUTH headers
this->http()->oauthToken(access_token.c_str());
// create our output/response buffer
HTTPText output(output_buffer,output_buffer_len);
// now make the HTTP(S) request
switch(verb) {
case GET:
status = this->http()->get(url,&output);
break;
case DELETE:
status = this->http()->del(url,&output);
break;
case POST:
if (input_data != NULL && input_data_len > 0) {
if (input_type == JSON) {
HTTPJson input_json(input_data,input_data_len);
status = this->http()->post(url,input_json,&output);
}
else {
HTTPText input_text(input_data,input_data_len);
status = this->http()->post(url,input_text,&output);
}
}
else {
// no input buffer!
this->logger()->log("invoke: ERROR HTTP(POST) requested but no input data provided... returning NULL");
}
break;
case PUT:
if (input_data != NULL && input_data_len > 0) {
if (input_type == JSON) {
HTTPJson input_json(input_data,input_data_len);
status = this->http()->put(url,input_json,&output);
}
else {
HTTPText input_text(input_data,input_data_len);
status = this->http()->put(url,input_text,&output);
}
}
else {
// no input buffer!
this->logger()->log("invoke: ERROR HTTP(PUT) requested but no input data provided... returning NULL");
}
break;
default:
// invalid HTTP verb
this->logger()->log("invoke: ERROR invalid HTTP verb (%d) provided... returning NULL",verb);
break;
}
}
}
else {
// no credentials
this->logger()->log("no/incomplete salesforce.com credentials provided. Unable to invoke API...");
}
// DEBUG
if (status == 0) this->logger()->log("invoke: SUCCESS!");
else this->logger()->log("invoke: FAILURE (%d)",status);
// return the response in the output buffer
if (status == 0) return output_buffer;
return NULL;
}
