Whitelist All IPs for Salesforce Chrome Extension

So it’s been awhile since Enable All Trusted IP Ranges for a Salesforce Org actually worked, because Salesforce disabled the ability for homepage components to run javascript around Summer, 2015.

There was a workaround logged as a Github issue which simply ran the javascript from the homepage component in the developer console, and that seemed to work, I referred people there. It wasn’t really elegant, but it worked.

I’ve had it on my plate to create a browser extension to perform this capability ever since. A few days ago, I was going to manually add an IP to Setup => Security Controls => Network Access, and I saw a button called “Allow All Ranges (!)”. I clicked it, and sure enough, it actually added all IP ranges! I looked through all of my installed Chrome extensions, and didn’t see any of them that advertised this feature. I disabled them one-by-one until I found the culprit: Apex Debugger by motiko. Browsing the source, motiko attributed my original post for that piece. I asked motiko about it in email, asked for permission to publish this feature standalone, and he agreed.

So I spent a couple hours, stripped out everything but this feature, packaged it up, paid the $5 registration fee, and put it on the Chrome Web store: https://chrome.google.com/webstore/detail/whitelist-all-ips-for-sal/nnlnikmkkbpgioojghgojoejgcheilic.

Here’s a quick video on how it works:

Please let me know if you have any questions via twitter. Cheers!

Oh, and the source is on github.

Comments Off

Apex: Booleans can be null

Apex on Salesforce is a subset of Java. In general a Java developer should feel right at home when creating Apex.

One of the things I encountered recently where Java and Apex differ is the ability to access Primitives. For example, Java has a boolean type, which can be true or false. Additionally, there’s a Boolean type, which can be true, false, or null, and can be used in Collections because it inherits from Object. If using the latter, the consumer need always check for null before checking true or false.

Apex does not have access to Primitive Data Types, only those which inherit from Object. Therefore this issue can result:

Boolean isError;
if (isError) {
  System.debug('Error!');
}

This will fail with:

System.NullPointerException: Attempt to de-reference a null object

Unless you instantiated the Boolean to a true/false, you must check for null before checking whether it’s true or false. Alternatively, you can explicitly check for true (which feels wrong, but would circumvent the issue):

Boolean isError;
if (isError == true) {
  System.debug('Error!');
}

No issue results.

I saw this recently when I queried a Checkbox field on an object. I created the Checkbox field AFTER the record was created, so each of the existing records default the Checkbox (Boolean) field to null, instead of false as you might expect.

In summary:
The Best Practice for dealing with Booleans in Apex is to explicitly check for == true/false

if (Boolean == true)

rather than use the shorthand.

if (Boolean)

Hat tip to Jeegar Brahmakshatriya for the help.

Tagged | Comments Off

Importing a java keystore jks file to Salesforce

I had a certificate which needed import into Salesforce, and one of the options provided to me was to put it into a java keystore, which could easily be imported. Since the file I had available to me wasn’t in the keystore format, I had to figure out how to import it into a keystore on my Mac using the keytool library. I had a pfx file to me, but the same principle can be applied to a .cer file as well.

Here are the commands using java’s keytool to perform this:


keytool -importkeystore -srckeystore {pfxfile} -srcstoretype pkcs12 -keystore keystore.jks

This prompted me for the passwords, and generated a keystore.jks file.

The key was imported into the keystore with the alias “le-9c090e06-14af-4ddd-b5fe-6ac9af45ea18″, which has an unacceptable format:

Error: Keystore contains an entry whose alias is not acceptable for import

Thanks to the Salesforce help, it was a quick and easy keytool command to rename it:

keytool -keystore keystore.jks -changealias -alias le-9c090e06-14af-4ddd-b5fe-6ac9af45ea18 -destalias {compliant_name}

I was then able to import the jks file into Salesforce via Setup => Security and Controls => Certificate and Key Management => Import from Keystore.

Tagged , , | Comments Off

Endpoint for Salesforce custom SOAP web service

It was surprising difficult to figure out what the endpoint should be for a custom SOAP web service created on Salesforce, probably due to the generic terms used.

When you create a custom soap web service in Salesforce, e.g.

and you want to figure out that URL to call it, you need simply do the following.

  1. Go to your class in Salesforce, Setup => Develop => Apex Classes => WebserviceExample (in my sample)
  2. Click the “Generate WSDL” button
  3. Look toward the bottom for the service element, and find the port’s soap:address element, and there it is! As of v32.0 it’s of the format: https://{node}.salesforce.com/services/Soap/class/{classname}

Here’s the portion of the WSDL you should find:

If you attempt to call your custom web service methods using the Partner WSDL, Enterprise WSDL, Apex, Metadata, etc. etc. you will presented with this error:

No operation available for request …

Tagged , , , | Comments Off

Using jquery selectors with dynamic visualforce

JQuery is a great js library, you can easily grab a component or list of components using any number of selectors.

Using it with visualforce can present a problem, however. When you specify an id attribute on a VF component, it outputs in a hierarchical colon separated value, for example:

<apex:page id="thePage">
  <apex:form id="theForm">
    <apex:outputPanel id="thePanel" />
  </apex:form>
</apex:page>

It will generate something of the following format for the innermost component:

<span id="thePage:theForm:thePanel" />

In order to reference this selector in JQuery, ideally you’d do the following:

$("#thePage:theForm:thePanel")

Unfortunately “:” is a special character in JQuery selectors, and will result in the following error:

Uncaught Syntax error, unrecognized expression: Syntax error, unrecognized expression: theForm

There are a number of ways to get around this.

  1. The simplest way is to provide a unique styleClass on the element, e.g.

        <apex:outputPanel id="thePanel" styleClass="thePanel" />
    

    which will generate

        <span id="thePage:theForm:thePanel" class="thePanel" />
    

    and at this point you can access it like this:

    $(".thePanel")
    

    Not a perfect solution, because classes really shouldn’t be forced to be unique, but it works.

  2. If you’re not accessing the id dynamically, you can double-blackslash escape the “:”, e.g.
    $("#thePage\\:theForm\\:thePanel")
    

    Kind of a pain, and ugly, but it works. If you are accessing the id dynamically with the $Component variable, e.g.

    {!$Component.thePage.theForm.thePanel}
    

    obviously you cannot double-blackslash escape without doing some javascript string replacement, but that’s even uglier.

  3. The easiest and seemingly best solution is to just pass the results of document.getElementById to the $() method, which can take an HTML object as a parameter, e.g.
    $(document.getElementById("thePage:theForm:thePanel"))
    

    or

    $(document.getElementById("{!$Component.thePage.theForm.thePanel}"))
    
  4. Seems to work in every scenario.

Tagged , | Comments Off

SOQL/SOSL: Using NOT LIKE

I’ve had to struggle to remember how to do this enough times that I think it’s worth documenting.

Using the LIKE keyword to filter records in a SOQL or SOSL query is a great way to do searching using a partial string match. Here’s an example:

  select Id, Name
  from Account
  where BillingState = 'WA'
    and Name like '%ray%'

But to exclude using the LIKE operator is a little more counter intuitive. Here’s the correct way to do it:

Good

  select Id, Name
  from Account
  where BillingState = 'WA'
    and (not Name like '%ray%')

Note that if you do any similar variants which you think might work, they will fail with the following error:

MALFORMED_QUERY … unexpected token: ‘not’

or

MALFORMED_QUERY … unexpected token: ‘like’

Here are some ways which you’d think might work, but do not.

Bad

  select Id, Name
  from Account
  where BillingState = 'WA'
    and not Name like '%ray%'

Bad

  select Id, Name
  from Account
  where BillingState = 'WA'
    and not (Name like '%ray%')

Bad

  select Id, Name
  from Account
  where BillingState = 'WA'
    and Name not like '%ray%'
Tagged , , | Comments Off