Salesforce.com interface to directly access Salesforce.com
Dependencies: HTTPClient-SSL MbedJSONValue
Dependents: df-2014-salesforce-hrm-k64f
Fork of SalesforceInterface by
SalesforceInterface.cpp@5:689831a2dc32, 2014-09-19 (annotated)
- Committer:
- ansond
- Date:
- Fri Sep 19 18:12:05 2014 +0000
- Revision:
- 5:689831a2dc32
- Parent:
- 1:a7dca096e47d
- Child:
- 7:97ea5ef906f7
hopefully final HTTP NXP buffer size tweak
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ansond | 0:518b1ca956fc | 1 | /* Copyright C2014 ARM, MIT License |
ansond | 0:518b1ca956fc | 2 | * |
ansond | 0:518b1ca956fc | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
ansond | 0:518b1ca956fc | 4 | * and associated documentation files the "Software", to deal in the Software without restriction, |
ansond | 0:518b1ca956fc | 5 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, |
ansond | 0:518b1ca956fc | 6 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
ansond | 0:518b1ca956fc | 7 | * furnished to do so, subject to the following conditions: |
ansond | 0:518b1ca956fc | 8 | * |
ansond | 0:518b1ca956fc | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
ansond | 0:518b1ca956fc | 10 | * substantial portions of the Software. |
ansond | 0:518b1ca956fc | 11 | * |
ansond | 0:518b1ca956fc | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
ansond | 0:518b1ca956fc | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
ansond | 0:518b1ca956fc | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
ansond | 0:518b1ca956fc | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
ansond | 0:518b1ca956fc | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
ansond | 0:518b1ca956fc | 17 | */ |
ansond | 0:518b1ca956fc | 18 | |
ansond | 0:518b1ca956fc | 19 | // Tuneables |
ansond | 0:518b1ca956fc | 20 | #define SF_OAUTH_TOKEN_URL "https://login.salesforce.com/services/oauth2/token" |
ansond | 0:518b1ca956fc | 21 | #define SF_OAUTH_REQUEST_BODY "grant_type=password&client_id=%s&client_secret=%s&username=%s&password=%s" |
ansond | 0:518b1ca956fc | 22 | #define SF_HTTP_AUTH_HEADER "Authorization: Bearer %s" |
ansond | 0:518b1ca956fc | 23 | #define MAX_BUFFER_LENGTH 1024 |
ansond | 0:518b1ca956fc | 24 | |
ansond | 0:518b1ca956fc | 25 | // convenience macros |
ansond | 0:518b1ca956fc | 26 | #define ALLOC_BUFFER(x) char x[MAX_BUFFER_LENGTH+1];memset(x,0,MAX_BUFFER_LENGTH+1); |
ansond | 0:518b1ca956fc | 27 | |
ansond | 0:518b1ca956fc | 28 | // include class definition |
ansond | 0:518b1ca956fc | 29 | #include "SalesforceInterface.h" |
ansond | 0:518b1ca956fc | 30 | |
ansond | 0:518b1ca956fc | 31 | // Supported DataTypes for HTTPClient |
ansond | 0:518b1ca956fc | 32 | #include "HTTPMap.h" |
ansond | 0:518b1ca956fc | 33 | #include "HTTPJson.h" |
ansond | 0:518b1ca956fc | 34 | |
ansond | 0:518b1ca956fc | 35 | // default constructor |
ansond | 0:518b1ca956fc | 36 | SalesforceInterface::SalesforceInterface(ErrorHandler *logger,HTTPClient *http) { |
ansond | 0:518b1ca956fc | 37 | this->m_logger = logger; |
ansond | 0:518b1ca956fc | 38 | this->m_http = http; |
ansond | 0:518b1ca956fc | 39 | this->m_username = NULL; |
ansond | 0:518b1ca956fc | 40 | this->m_password = NULL; |
ansond | 0:518b1ca956fc | 41 | this->m_client_id = NULL; |
ansond | 0:518b1ca956fc | 42 | this->m_client_secret = NULL; |
ansond | 0:518b1ca956fc | 43 | this->m_have_creds = false; |
ansond | 0:518b1ca956fc | 44 | } |
ansond | 0:518b1ca956fc | 45 | |
ansond | 0:518b1ca956fc | 46 | // destructor |
ansond | 0:518b1ca956fc | 47 | SalesforceInterface::~SalesforceInterface() { |
ansond | 0:518b1ca956fc | 48 | } |
ansond | 0:518b1ca956fc | 49 | |
ansond | 0:518b1ca956fc | 50 | // set credentials |
ansond | 0:518b1ca956fc | 51 | void SalesforceInterface::setCredentials(char *username,char *password,char *client_id,char *client_secret) { |
ansond | 0:518b1ca956fc | 52 | this->m_username = NULL; |
ansond | 0:518b1ca956fc | 53 | this->m_password = NULL; |
ansond | 0:518b1ca956fc | 54 | this->m_client_id = NULL; |
ansond | 0:518b1ca956fc | 55 | this->m_client_secret = NULL; |
ansond | 0:518b1ca956fc | 56 | this->m_have_creds = false; |
ansond | 0:518b1ca956fc | 57 | |
ansond | 0:518b1ca956fc | 58 | if (username != NULL) { |
ansond | 0:518b1ca956fc | 59 | this->m_username = username; |
ansond | 0:518b1ca956fc | 60 | if (password != NULL) { |
ansond | 0:518b1ca956fc | 61 | this->m_password = password; |
ansond | 0:518b1ca956fc | 62 | if (client_id != NULL) { |
ansond | 0:518b1ca956fc | 63 | this->m_client_id = client_id; |
ansond | 0:518b1ca956fc | 64 | if (client_secret != NULL) { |
ansond | 0:518b1ca956fc | 65 | this->m_client_secret = client_secret; |
ansond | 0:518b1ca956fc | 66 | this->m_have_creds = true; |
ansond | 0:518b1ca956fc | 67 | } |
ansond | 0:518b1ca956fc | 68 | } |
ansond | 0:518b1ca956fc | 69 | } |
ansond | 0:518b1ca956fc | 70 | } |
ansond | 0:518b1ca956fc | 71 | } |
ansond | 0:518b1ca956fc | 72 | |
ansond | 0:518b1ca956fc | 73 | // convenience accessors |
ansond | 0:518b1ca956fc | 74 | ErrorHandler *SalesforceInterface::logger() { return this->m_logger; } |
ansond | 0:518b1ca956fc | 75 | HTTPClient *SalesforceInterface::http() { return this->m_http; } |
ansond | 0:518b1ca956fc | 76 | bool SalesforceInterface::haveCreds() { return this->m_have_creds; } |
ansond | 0:518b1ca956fc | 77 | |
ansond | 0:518b1ca956fc | 78 | // |
ansond | 0:518b1ca956fc | 79 | // get OAUTH2 Token - taken from here: |
ansond | 0:518b1ca956fc | 80 | // 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 |
ansond | 0:518b1ca956fc | 81 | // |
ansond | 0:518b1ca956fc | 82 | char *SalesforceInterface::getOauthToken(char *output_buffer,int output_buffer_length) { |
ansond | 1:a7dca096e47d | 83 | if (this->haveCreds()) { |
ansond | 0:518b1ca956fc | 84 | // construct the OAUTH2 Token request body |
ansond | 0:518b1ca956fc | 85 | HTTPMap input; |
ansond | 0:518b1ca956fc | 86 | |
ansond | 0:518b1ca956fc | 87 | // |
ansond | 0:518b1ca956fc | 88 | // FORMAT: Taken from URL above method signature: |
ansond | 0:518b1ca956fc | 89 | // |
ansond | 0:518b1ca956fc | 90 | // grant_type=password&client_id=<your_client_id>&client_secret=<your_client_secret>&username=<your_username>&password=<your_password> |
ansond | 0:518b1ca956fc | 91 | // |
ansond | 0:518b1ca956fc | 92 | // ContentType: application/x-www-form-urlencoded |
ansond | 0:518b1ca956fc | 93 | // |
ansond | 0:518b1ca956fc | 94 | input.put("grant_type","password"); |
ansond | 0:518b1ca956fc | 95 | input.put("client_id",this->m_client_id); |
ansond | 0:518b1ca956fc | 96 | input.put("client_secret",this->m_client_secret); |
ansond | 0:518b1ca956fc | 97 | input.put("username",this->m_username); |
ansond | 0:518b1ca956fc | 98 | input.put("password",this->m_password); |
ansond | 1:a7dca096e47d | 99 | |
ansond | 0:518b1ca956fc | 100 | // prepare the output buffer |
ansond | 0:518b1ca956fc | 101 | HTTPText output(output_buffer,output_buffer_length); |
ansond | 0:518b1ca956fc | 102 | |
ansond | 0:518b1ca956fc | 103 | // HTTP POST call to gett he token |
ansond | 0:518b1ca956fc | 104 | DEBUG("getOauthToken: Calling %s...",SF_OAUTH_TOKEN_URL); |
ansond | 0:518b1ca956fc | 105 | HTTPResult status = this->http()->post(SF_OAUTH_TOKEN_URL,input,&output); |
ansond | 0:518b1ca956fc | 106 | |
ansond | 0:518b1ca956fc | 107 | // check the result and return the token |
ansond | 0:518b1ca956fc | 108 | DEBUG("getOauthToken: status(%d) response: %s",status,output_buffer); |
ansond | 0:518b1ca956fc | 109 | if (status == 0) return output_buffer; |
ansond | 0:518b1ca956fc | 110 | } |
ansond | 0:518b1ca956fc | 111 | else { |
ansond | 0:518b1ca956fc | 112 | // no credentials |
ansond | 0:518b1ca956fc | 113 | this->logger()->log("no/incomplete salesforce.com credentials provided. Unable to acquire OAUTH2 token..."); |
ansond | 0:518b1ca956fc | 114 | } |
ansond | 0:518b1ca956fc | 115 | return NULL; |
ansond | 0:518b1ca956fc | 116 | } |
ansond | 0:518b1ca956fc | 117 | |
ansond | 0:518b1ca956fc | 118 | // Salesforce.com Invoke: defaults to GET |
ansond | 0:518b1ca956fc | 119 | char *SalesforceInterface::invoke(char *url,char *output_buffer,int output_buffer_len) { |
ansond | 0:518b1ca956fc | 120 | return this->invoke(url,NUM_TYPES,NULL,0,output_buffer,output_buffer_len,GET); |
ansond | 0:518b1ca956fc | 121 | } |
ansond | 0:518b1ca956fc | 122 | |
ansond | 0:518b1ca956fc | 123 | // Salesforce.com Invoke: defaults to POST with JSON input data type |
ansond | 0:518b1ca956fc | 124 | char *SalesforceInterface::invoke(char *url,char *input_data,int input_data_len,char *output_buffer,int output_buffer_len) { |
ansond | 0:518b1ca956fc | 125 | return this->invoke(url,JSON,input_data,input_data_len,output_buffer,output_buffer_len); |
ansond | 0:518b1ca956fc | 126 | } |
ansond | 0:518b1ca956fc | 127 | |
ansond | 0:518b1ca956fc | 128 | // Salesforce.com Invoke: defaults to POST with variable input data type |
ansond | 0:518b1ca956fc | 129 | char *SalesforceInterface::invoke(char *url,InputDataTypes input_type,char *input_data,int input_data_len,char *output_buffer,int output_buffer_len) { |
ansond | 0:518b1ca956fc | 130 | return this->invoke(url,input_type,input_data,input_data_len,output_buffer,output_buffer_len,POST); |
ansond | 0:518b1ca956fc | 131 | } |
ansond | 0:518b1ca956fc | 132 | |
ansond | 0:518b1ca956fc | 133 | // Salesforce.com Invoke: full fidelity method |
ansond | 0:518b1ca956fc | 134 | char *SalesforceInterface::invoke(char *url,InputDataTypes input_type,char *input_data,int input_data_len,char *output_buffer,int output_buffer_len,HttpVerb verb) { |
ansond | 0:518b1ca956fc | 135 | // initialize our invocation status |
ansond | 0:518b1ca956fc | 136 | HTTPResult status = HTTP_ERROR; |
ansond | 0:518b1ca956fc | 137 | |
ansond | 0:518b1ca956fc | 138 | if (this->haveCreds() && output_buffer != NULL && output_buffer_len > 0) { |
ansond | 0:518b1ca956fc | 139 | // first we have to get our OAUTH2 Token |
ansond | 0:518b1ca956fc | 140 | ALLOC_BUFFER(token_buffer); |
ansond | 0:518b1ca956fc | 141 | |
ansond | 0:518b1ca956fc | 142 | // get the OAUTH2 token |
ansond | 0:518b1ca956fc | 143 | char *token = this->getOauthToken(token_buffer,sizeof(token_buffer)); |
ansond | 0:518b1ca956fc | 144 | if (token != NULL) { |
ansond | 0:518b1ca956fc | 145 | // Parse the OAUTH2 token |
ansond | 0:518b1ca956fc | 146 | MbedJSONValue parsed_token; |
ansond | 0:518b1ca956fc | 147 | parse(parsed_token,token); |
ansond | 0:518b1ca956fc | 148 | |
ansond | 0:518b1ca956fc | 149 | // extract the OAUTH2 token |
ansond | 0:518b1ca956fc | 150 | string access_token = parsed_token["access_token"].get<std::string>(); |
ansond | 0:518b1ca956fc | 151 | |
ansond | 0:518b1ca956fc | 152 | // DEBUG |
ansond | 0:518b1ca956fc | 153 | this->logger()->log("OAUTH: %s",access_token.c_str()); |
ansond | 0:518b1ca956fc | 154 | |
ansond | 0:518b1ca956fc | 155 | // use OAUTH headers |
ansond | 0:518b1ca956fc | 156 | this->http()->oauthToken(access_token.c_str()); |
ansond | 0:518b1ca956fc | 157 | |
ansond | 0:518b1ca956fc | 158 | // create our output/response buffer |
ansond | 0:518b1ca956fc | 159 | HTTPText output(output_buffer,output_buffer_len); |
ansond | 0:518b1ca956fc | 160 | |
ansond | 0:518b1ca956fc | 161 | // now make the HTTP(S) request |
ansond | 0:518b1ca956fc | 162 | switch(verb) { |
ansond | 0:518b1ca956fc | 163 | case GET: |
ansond | 0:518b1ca956fc | 164 | status = this->http()->get(url,&output); |
ansond | 0:518b1ca956fc | 165 | break; |
ansond | 0:518b1ca956fc | 166 | case DELETE: |
ansond | 0:518b1ca956fc | 167 | status = this->http()->del(url,&output); |
ansond | 0:518b1ca956fc | 168 | break; |
ansond | 0:518b1ca956fc | 169 | case POST: |
ansond | 0:518b1ca956fc | 170 | if (input_data != NULL && input_data_len > 0) { |
ansond | 0:518b1ca956fc | 171 | if (input_type == JSON) { |
ansond | 0:518b1ca956fc | 172 | HTTPJson input_json(input_data,input_data_len); |
ansond | 0:518b1ca956fc | 173 | status = this->http()->post(url,input_json,&output); |
ansond | 0:518b1ca956fc | 174 | } |
ansond | 0:518b1ca956fc | 175 | else { |
ansond | 0:518b1ca956fc | 176 | HTTPText input_text(input_data,input_data_len); |
ansond | 0:518b1ca956fc | 177 | status = this->http()->post(url,input_text,&output); |
ansond | 0:518b1ca956fc | 178 | } |
ansond | 0:518b1ca956fc | 179 | } |
ansond | 0:518b1ca956fc | 180 | else { |
ansond | 0:518b1ca956fc | 181 | // no input buffer! |
ansond | 0:518b1ca956fc | 182 | this->logger()->log("invoke: ERROR HTTP(POST) requested but no input data provided... returning NULL"); |
ansond | 0:518b1ca956fc | 183 | } |
ansond | 0:518b1ca956fc | 184 | break; |
ansond | 0:518b1ca956fc | 185 | case PUT: |
ansond | 0:518b1ca956fc | 186 | if (input_data != NULL && input_data_len > 0) { |
ansond | 0:518b1ca956fc | 187 | if (input_type == JSON) { |
ansond | 0:518b1ca956fc | 188 | HTTPJson input_json(input_data,input_data_len); |
ansond | 0:518b1ca956fc | 189 | status = this->http()->put(url,input_json,&output); |
ansond | 0:518b1ca956fc | 190 | } |
ansond | 0:518b1ca956fc | 191 | else { |
ansond | 0:518b1ca956fc | 192 | HTTPText input_text(input_data,input_data_len); |
ansond | 0:518b1ca956fc | 193 | status = this->http()->put(url,input_text,&output); |
ansond | 0:518b1ca956fc | 194 | } |
ansond | 0:518b1ca956fc | 195 | } |
ansond | 0:518b1ca956fc | 196 | else { |
ansond | 0:518b1ca956fc | 197 | // no input buffer! |
ansond | 0:518b1ca956fc | 198 | this->logger()->log("invoke: ERROR HTTP(PUT) requested but no input data provided... returning NULL"); |
ansond | 0:518b1ca956fc | 199 | } |
ansond | 0:518b1ca956fc | 200 | break; |
ansond | 0:518b1ca956fc | 201 | default: |
ansond | 0:518b1ca956fc | 202 | // invalid HTTP verb |
ansond | 0:518b1ca956fc | 203 | this->logger()->log("invoke: ERROR invalid HTTP verb (%d) provided... returning NULL",verb); |
ansond | 0:518b1ca956fc | 204 | break; |
ansond | 0:518b1ca956fc | 205 | } |
ansond | 0:518b1ca956fc | 206 | } |
ansond | 0:518b1ca956fc | 207 | } |
ansond | 0:518b1ca956fc | 208 | else { |
ansond | 0:518b1ca956fc | 209 | // no credentials |
ansond | 0:518b1ca956fc | 210 | this->logger()->log("no/incomplete salesforce.com credentials provided. Unable to invoke API..."); |
ansond | 0:518b1ca956fc | 211 | } |
ansond | 0:518b1ca956fc | 212 | |
ansond | 0:518b1ca956fc | 213 | // DEBUG |
ansond | 0:518b1ca956fc | 214 | if (status == 0) this->logger()->log("invoke: SUCCESS!"); |
ansond | 0:518b1ca956fc | 215 | else this->logger()->log("invoke: FAILURE (%d)",status); |
ansond | 0:518b1ca956fc | 216 | |
ansond | 0:518b1ca956fc | 217 | // return the response in the output buffer |
ansond | 0:518b1ca956fc | 218 | if (status == 0) return output_buffer; |
ansond | 0:518b1ca956fc | 219 | return NULL; |
ansond | 0:518b1ca956fc | 220 | } |
ansond | 0:518b1ca956fc | 221 |