Friday, December 23, 2016

Enabling Debug Log for Public User (Guest User license) after Winter 17 Release

Before winter 17 release, you can enable debug logs for site users (Guest users related to force.com sites) but after winter 17 release, Salesforce is not capturing the logs of site users as large number of events can quickly fill the debug logs.

So in order to enable logs for site users if you have to debug some issue related to VF page hosted on force.com site, then you have to set special cookie in user's browser.

Follow below steps in order to set cookie in google chrome:

  • Navigate to your site.
  • Open Chrome Developer tools or press Cntrl + Shift + J.
  • Enter below instruction to set cookie
    • If you use a .force.com domain, use this command. document.cookie="debug_logs=debug_logs;domain=.force.com";

    • If you use a custom domain (for example, myTestDomain.com), then use document.cookie="debug_logs=debug_logs;domain=myTestDomain.com";
To set a browser cookie in for other browsers, you have to install a plug-in or extension.



Tuesday, December 13, 2016

Best way to deal with user supplied inputs in dynamic SOQL query -SOQL Injection

Through SOQL Injection, end user can play with the data present in your organization. End users can specify input which can alter your dynamic SOQL query and return sensitive data to user on UI.

Consider a scenario where user search account present in your org by specifying account name as a search text. Below is sample VF and apex code which explain SOQL injection.

Suppose you enter "test" and click on search, system will return all account name as test. Below is SOQL query which will be executed:

SELECT Id, name, industry, BillingStreet, BillingState, BillingCity, BillingCountry FROM Account WHERE Name like '%test%' 


Now if you enter " test%' OR Name LIKE '% " and click on search account button, then system will return all account in system. 

Actually after entering above text, SOQL query will become like this:

SELECT Id, name, industry, BillingStreet, BillingState, BillingCity, BillingCountry FROM Account WHERE Name like '%test%' OR Name LIKE '%%' 



SOQL injection allow end users to reconstruct your SOQL and fetch sensitive data from your org.

Resolution:

  • Try to use static SOQL and bind user input variable in that.
  • If you have to use dynamic SOQL for your requirement, then user use the escapeSingleQuotes method for all user input strings. This add escape character (\) to all single quotation marks in string that is specified by end user. 

Below is modified apex code to avoid SOQL injection:

public PageReference query() {
        if(name !=null && name !=''){
            name = String.escapeSingleQuotes(name);
            accList = new List<Account>();
            queryString= 'SELECT Id, name, industry, BillingStreet, BillingState, BillingCity, BillingCountry   FROM Account WHERE ' + ' Name like \'%' + name + '%\'';
            accList = Database.query(queryString);
        }else{
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'Please enter search text value'));
        }
        return null;
    }

Now if user enter " test%' OR Name LIKE '% "  and click on search account button, the dynamic SOQL query will become as mentioned below and system will not display anything on UI.

SELECT Id, name, industry, BillingStreet, BillingState, BillingCity, BillingCountry FROM Account WHERE Name like '%test%\' OR Name LIKE \'%%' 


Saturday, December 10, 2016

Round Off Field Values in VF page

Suppose a field (Opportunity Amount field) value is 12.34 and you have to round off it to 1 decimal places on VF page, Then use below syntax:


<apex:page standardController="opportunity" >
<apex:outputText value="{0, number, ###,###.0}">
<apex:param value="{!opportunity.amount}"/>
</apex:outputText>

</apex:page>

Output on VF page will be 12.3

Note: This work perfectly for number ,percent, and currency fields.



Refer Below Links for Salesforce Interview Questions


Friday, December 9, 2016

Date field Formatting on VF page

If you have to format Date fields directly on VF page, then you can use below code snippets to achieve this.

<apex:page standardController="Opportunity">
    <!--display=10/25-->
    <apex:outputlabel value="Opportunity Close date (MM/dd):" />
    <apex:outputText value="{0,date,MM/dd}">
        <apex:param value="{!opportunity.CloseDate}"  />                              
    </apex:outputText>
    <br/>

    <!--display=October 25-->
    <apex:outputlabel value="Opportunity Close date (MMMM dd): " />
    <apex:outputText value="{0,date,MMMM dd}">
        <apex:param value="{!opportunity.CloseDate}"  />  
    </apex:outputText>
    <br/>
    
    <!--display= display=25 October-->
    <apex:outputlabel value="Opportunity Close date (dd MMMM): " />
    <apex:outputText value="{0,date,dd MMMM}">
        <apex:param value="{!opportunity.CloseDate}"  />                                   
    </apex:outputText>
    <br/>
    
    <!--  display=DD/MM-->
    <apex:outputlabel value="Opportunity Close date (DD/MM): " />
    {!Day(opportunity.CloseDate)}/{!Month(opportunity.CloseDate)}                           
</apex:page>


Output on VF Page:

08/06 
August 06 
06 August 
6/8







Refer Below Links for Salesforce Interview Questions





Wednesday, December 7, 2016

Encoding and Decoding Data in Salesforce

EncodingUtil class in apex provides ability to encode and decode URL strings, and convert strings to hexadecimal format. 

Common use case can be like you want to store password of third party application which can be used while performing callout. So instead of storing the password, store encode format of password and and decode it while performing callout. Below is sample code which uses EncodingUtil methods to encode string and then decoding it back to string.

String password = 'Password123';
system.debug('******password' + password);
system.debug('******password Blob' + blob.valueof(password));
String encodedPassword = EncodingUtil.base64Encode(blob.valueof(password));
system.debug('********encodedPassword:' + encodedPassword);
blob decodedPasswordBlob = EncodingUtil.base64Decode(encodedPassword);
system.debug('********decodedPassword Blob:' + decodedPasswordBlob);
system.debug('********decodedPassword:' + decodedPasswordBlob.tostring());












Suppose you have to pass some parameters while performing callout, then you can encode your url parameters.
For example you have to send timestamp in url in yyyy-MM-dd'T'HH:mm:ss.SSS'Z' format. Below is sample code.

DateTime d = System.now();
String timestamp = ''+ d.year() + '-' +
d.month() + '-' +
d.day() + '\'T\'' +
d.hour() + ':' +
d.minute() + ':' +
d.second() + '.' +
d.millisecond() + '\'Z\'';
     
system.debug('********timestamp:'+timestamp);
String urlEncodedTimestamp = EncodingUtil.urlEncode(timestamp, 'UTF-8');
system.debug('********urlEncodedTimestamp:'+urlEncodedTimestamp);
//then you can append it to URL parameters. You can use below method to decode URL encoded strings.
String urlDecodedTimestamp = EncodingUtil.urlDecode(urlEncodedTimestamp, 'UTF-8');
system.debug('********urlDecodedTimestamp:'+urlDecodedTimestamp);