If I wanted to distribute something using this through the AppExchange, should I have to include instructions to add the endpoint in the remote site settings? Or is there a way to automate this setting during installation?
You can set them up from Javascript using a welcome page. Fawcett's own open source code base has a few examples of such behavior, including in the Apex Wrapper for the Metadata API. There's some additional markup, but here's the script involved:
function createRemoteSite()
{
// Disable button
document.getElementById('createremotesitebtn').disabled = true;
// Calls the Metdata API from JavaScript to create the Remote Site Setting to permit Apex callouts
var binding = new XMLHttpRequest();
var request =
'<?xml version="1.0" encoding="utf-8"?>' +
'<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'+
'<env:Header>' +
'<urn:SessionHeader xmlns:urn="http://soap.sforce.com/2006/04/metadata">' +
'<urn:sessionId>{!$Api.Session_ID}</urn:sessionId>' +
'</urn:SessionHeader>' +
'</env:Header>' +
'<env:Body>' +
'<createMetadata xmlns="http://soap.sforce.com/2006/04/metadata">' +
'<metadata xsi:type="RemoteSiteSetting">' +
'<fullName>{!RemoteSiteName}</fullName>' +
'<description>Metadata API Remote Site Setting for Declarative Rollup Tool (DLRS)</description>' +
'<disableProtocolSecurity>false</disableProtocolSecurity>' +
'<isActive>true</isActive>' +
'<url>https://{!Host}</url>' +
'</metadata>' +
'</createMetadata>' +
'</env:Body>' +
'</env:Envelope>';
binding.open('POST', 'https://{!Host}/services/Soap/m/31.0');
binding.setRequestHeader('SOAPAction','""');
binding.setRequestHeader('Content-Type', 'text/xml');
binding.onreadystatechange =
function() {
if(this.readyState==4) {
var parser = new DOMParser();
var doc = parser.parseFromString(this.response, 'application/xml');
var errors = doc.getElementsByTagName('errors');
var messageText = '';
for(var errorIdx = 0; errorIdx < errors.length; errorIdx++)
messageText+= errors.item(errorIdx).getElementsByTagName('message').item(0).innerHTML + '\n';
displayMetadataResponse(messageText);
}
}
binding.send(request);
}
To my understanding, several tools (Like Mavensmate and Atom, Sublime and VSCode extensions) make use of the Tooling API and they never ask for security settings in the target instance, how can they achieve that?
The issue here is you have to whitelist endpoints to which you can make outbound calls, specifically using Apex
. Any IDE will be making the outbound call using its own stack, and hence there is no mechanism enforcing that calls only be made to endpoints which are whitelisted in Salesforce.