[SalesForce] How to make signed request to Salesforce using an Access token and SOAP api

I'm working on Salesforce integration to (1) upload file attachments to Salesforce and (2) make signed requests/API call to Salesforce using the access token that we already have. Uploading files to SF using REST is not an option for us since we are not in pilot program as describe here. So we used Beatbox to upload files to SF and that uses SOAP api. Now since we're using Beatbox we also wanted to make signed request to SF API using an access token that we already have. Looking at Beatbox source there is useSession(sessionId, serverUrl), now I can replace sessionId with access token and put a hard coded server url and I can make signed request to SF with that, problem is serverUrl is changing. Using just the access token can I get the serverUrl in advance so that I can use it with useSession()? If not possible, what are other alternatives?

Update: I added a simple helper method to beatbox.py for our requirement though some might find it useful. Credits to metadaddy for the solution.

def oauth_login(self, sessionId, orgId, userId):
    url = 'https://login.salesforce.com/id/%s/%s' % (orgId, userId)
    headers = { 
        'Authorization': 'Bearer %s' % sessionId 
    }   
    params = {'version':'latest'}
    resp = requests.post(url, params=params, headers=headers, allow_redirects=True)
    content = json.loads(resp.content)
    serverUrl = str(content.get('urls')['partner']).encode('UTF-8')
    self.useSession(sessionId, serverUrl)

Usage:

import beatbox
sf = beatbox._tPartnerNS
svc = beatbox.Client()

access_token = ''
orgId = ''
userId = ''

svc.oauth_login(access_token, orgId, userId)
qr = svc.query("select Id, Name from Account")
print "query size = " + str(qr[sf.size])

Best Answer

The OAuth 2.0 response includes the id property, which is a URL for the Identity Service, with the format

https://login.salesforce.com/id/[ORG_ID]/[USER_ID]

Invoke this URL with the access token, and you'll receive a JSON object with a bunch of useful data including the Partner API server URL. I don't have a Python example handy, but here's an example using command-line curl. Note the -L parameter - you need to follow the redirect, and the version=latest query parameter just says you want the latest API version URLs:

$ curl -L -H 'Authorization: Bearer 00DE0000000HegH!AREAQBXmi3kZkq.14qNdqVUAhdmdj8jCvSnZhsdDck.xhFwoaxUdgG6fiqY3OKebwLQoRnSudnpNHsrC30xaqk8R8ZRX1eJS' -H 'X-PrettyPrint: 1' https://login.salesforce.com/id/00DE0000000HegHMAS/005E0000000HiFiIAK?version=latest
{
  "id" : "https://login.salesforce.com/id/00DE0000000HegHMAS/005E0000000HiFiIAK",
  "asserted_user" : true,
  "user_id" : "005E0000000HiFiIAK",
  "organization_id" : "00DE0000000HegHMAS",
  "username" : "pat@devorg.com",
  "nick_name" : "pat1.2979659540664607E12",
  "display_name" : "Pat Patterson",
  "email" : "ppatterson@salesforce.com",
  "first_name" : "Pat",
  "last_name" : "Patterson",
  "status" : {
    "created_date" : null,
    "body" : null
  },
  "photos" : {
    "picture" : "https://devorg-com-dev-ed--c.na9.content.force.com/profilephoto/729E0000000Ubc9/F",
    "thumbnail" : "https://devorg-com-dev-ed--c.na9.content.force.com/profilephoto/729E0000000Ubc9/T"
  },
  "urls" : {
    "enterprise" : "https://devorg-com-dev-ed.my.salesforce.com/services/Soap/c/29.0/00DE0000000HegH",
    "metadata" : "https://devorg-com-dev-ed.my.salesforce.com/services/Soap/m/29.0/00DE0000000HegH",
    "partner" : "https://devorg-com-dev-ed.my.salesforce.com/services/Soap/u/29.0/00DE0000000HegH",
    "rest" : "https://devorg-com-dev-ed.my.salesforce.com/services/data/v29.0/",
    "sobjects" : "https://devorg-com-dev-ed.my.salesforce.com/services/data/v29.0/sobjects/",
    "search" : "https://devorg-com-dev-ed.my.salesforce.com/services/data/v29.0/search/",
    "query" : "https://devorg-com-dev-ed.my.salesforce.com/services/data/v29.0/query/",
    "recent" : "https://devorg-com-dev-ed.my.salesforce.com/services/data/v29.0/recent/",
    "profile" : "https://devorg-com-dev-ed.my.salesforce.com/005E0000000HiFiIAK",
    "feeds" : "https://devorg-com-dev-ed.my.salesforce.com/services/data/v29.0/chatter/feeds",
    "groups" : "https://devorg-com-dev-ed.my.salesforce.com/services/data/v29.0/chatter/groups",
    "users" : "https://devorg-com-dev-ed.my.salesforce.com/services/data/v29.0/chatter/users",
    "feed_items" : "https://devorg-com-dev-ed.my.salesforce.com/services/data/v29.0/chatter/feed-items",
    "custom_domain" : "https://devorg-com-dev-ed.my.salesforce.com"
  },
  "active" : true,
  "user_type" : "STANDARD",
  "language" : "en_US",
  "locale" : "en_US",
  "utcOffset" : -28800000,
  "last_modified_date" : "2013-06-19T17:19:41.000+0000"
}

The URL you are looking for is urls.partner, which is https://devorg-com-dev-ed.my.salesforce.com/services/Soap/u/29.0/00DE0000000HegH in the above example.

Related Topic