Pages

Wednesday, March 30, 2016

Salesforce Force.com IDE superpowers uncovered

Disclaimer: I've been informed by Salesforce that this an exceptional case for functionality is still being refined and will likely be exposed broadly in a future API version (#SafeHarbour). Although perhaps not in this exact form. As with all undocumented API features they could disappear at any time in a future release.

Borrowing the Warranty phrasing from Scott Hanselman:
Of course, this is just some dude's blog. Depending on undocumented API functionality is a recipe for losing your job and a messy divorce. Salesforce are likely to make changes to the existing functionality between major releases. As they don't know you are using this functionality they won't tell you. There's no warranty, express or implied. I don't know you and I don't how how you got here. Stop calling. Jimmy no live here, you no call back! [My current landline phone number used to belong to a Thai takeaway shop - True Story]

My blog disclaimer also applies.


In putting together an answer to a Salesforce StackExchange question I came across something odd with the Force.com IDE source code. The question needed a way to find details about installed packages.

I knew from my keyprefix list that InstalledPackageVersion existed. It wasn't, however, exposed via SOQL to the Partner API or Tooling API. So why then when I was Googling around does it show up in the source code for the Force.com IDE in a SOQL query?:

    // P A C K A G E S
    DEVELOPMENT_PACKAGES("SELECT Id, Name, Description, IsManaged FROM DevelopmentPackageVersion"),
    INSTALL_PACKAGES("SELECT Id, Name, Description, IsManaged, VersionName FROM InstalledPackageVersion"),

What makes the Force.com IDE so special that it can run SOQL queries that other API users can't?

The answer lies in the SOAP API CallOptions.client header. The docs say this is "A string that identifies a client.". I've used it before in the past after passing the app exchange security review to access the Partner API in professional edition orgs. It turns out this is also the key to accessing the hidden abilities of the Force.com IDE. Again from the source code for the Force.com IDE:

    //value is critical for Eclipse-only API support
    private final String clientIdName = "apex_eclipse";

This is later combined with the API version to create the callOptions header.

So what if we use the same string when we establish our Session using the Partner API and then on subsequent calls?

The FuseIT SFDC Explorer supports setting the Client Id on the login New Connection screen and on a saved connection string.

   <add name="ForceCom IDE Login" 
     connectionString="G4S:user id=user@example.com;password=shhSecret;environment=Production;Client=apex_eclipse/v36.0"/>

The raw SOAP POST request:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Header>
    <CallOptions xmlns="urn:partner.soap.sforce.com">
      <client>apex_eclipse/v36.0</client>
    </CallOptions>
    <SessionHeader xmlns="urn:partner.soap.sforce.com">
      <sessionId>00D300000000001!AQ0AQDxJ1jtrcX3XNotARealSessionIdThatYouCanUseOAgFtJDkHc.IQ6Wjv6b1rTp7qQlNMOOFcZj6</sessionId>
    </SessionHeader>
  </soap:Header>
  <soap:Body>
    <-- etc... -->
  </soap:Body>

Now we be access to additional sObject Types that were previously inaccessible. So far I've tried:

  • DevelopmentPackageVersion
  • InstalledPackageVersion
  • ApexClassIdentifier
  • ApexClassIdentifierRelationship

I'll do some more poking around as time permits to see if there are any other hidden treasures.

No comments:

Post a Comment