Sunday, September 14, 2014

SOQL Injection in Salesforce?

SOQL Injection in Salesforce?

Suppose you have a search form and instead of typing a valid search parameter, User types something invalid text  and that can make your SOQL query invalid and expose the unexpected result.

This situation occurs when user input is not filtered for escape characters. let's have a pictorial look :






It's a SQL example , but describe the SOQL injection as well in a good manner.
So here you can see that. In the User id field once user puts a invalid parameter and goes to the controller and form a query that  results in a invalid login.

The worst scenario could be if resultant data from a query supposed to be deleted.
 let's have one more quick example for this :

I have a case where I want to delete the Account based on name entered in the input name field on page.
Implementation can be like this :

List<Account> listAccount = Database.query('Select id from Account where Name = \'' + nameField + '\' '); 

delete listAccount;


It works great with a valid value.
 Now it can be worst if value of nameField is provided like :

nameField = \' OR Id != null OR Type != \'


So once the action will be performed, this will be bind-up with the query and resultant query will be like this :
  

List<Account> listAccount = Database.query('Select id from Account where Name = \'\'\' OR ID != null OR Type != \'\' ');

delete  listAccount;


So hopefully , you can see the monster  here. It will delete the entire database for account records.

Salesforce provides escape functions to get rid from SOQL injection. 
Solution can be one of the followings:
  1. Try to use STATIC queries as much as possible. STATIC query has inbuilt escaping.
  2. If dynamic query is needed , then all the search parameters should use escapeSingleQuotes() function.like
    List<Account> listAccount = Database.query('Select id from Account where Name = \'' + String.escapeSingleQuotes(nameField) + '\' ');
String.escapeSingleQuotes method adds the escape character (\) to all single quotation marks in a string that is passed in from a user. The method ensures that all single quotation marks are treated as enclosing strings, instead of database commands.








Saturday, September 13, 2014

How to call Apex class method from Javascript Custom Button?

How to call Apex class method from Javascript Custom Button?

In this post i am giving an example of how to call Apex Class method when ever we click on custom button. i this scenario i have one custom button that is created in my project custom object and place in details page layout.

Custom Button Code:

{!REQUIRESCRIPT(""/soap/ajax/18.0/connection.js"")} 
{!REQUIRESCRIPT(""/soap/ajax/18.0/apex.js"")} 

var id = sforce.apex.execute(""Projectctrl"",""createProject"",{easySupportId:""{!Support__c.Id}""});

location.reload();

Apex Class:

global class Projectctrl {
 webservice static Id createProject(String easySupportId){
  
  Support__c  supportobj=[select id,Category__c,OwnerId from Support__c where id=:easySupportId];
  
  SFDC_Project__c  projObj=new SFDC_Project__c();
  projObj.Easy_Support_No__c=supportobj.id;
  projObj.Road_Map_Identification__c='Enable';
  if(supportObj.Category__c=='Project')
   projObj.Request_Type__c='Project';
  else
   projObj.Request_Type__c='Minor Enhancement'; 
  projObj.Estimated_Monthly_Release__c=String.valueOf(System.today().month()+1);
  projObj.User_project_requested_by__c=supportObj.OwnerId;
  insert projObj;
  SFDC_Project__c sfdcProjectObj=[select Name from SFDC_Project__c where id=:projObj.Id];
  projObj.SFDC_Project_Name__c='Project-'+sfdcProjectObj.Name;
  update projObj;
  return projObj.id;
 }
}


Test class:

@isTest(seeAllData=true)
private class TestProjectctrl {

    static testMethod void myUnitTest() {
        // TO DO: implement unit test
        Support__c  supportobj=new Support__c();
        supportobj.Category__c='Project';
        supportobj.ContactName__c=UserInfo.getUserId();
        supportobj.Contact_No__c='9246263254';
        supportobj.Description__c='Test description';
        insert supportobj;
        Projectctrl.createProject(supportobj.id);
        
    }
    static testMethod void myUnitTest1() {
        // TO DO: implement unit test
        Support__c  supportobj=new Support__c();
        supportobj.Category__c='Others';
        supportobj.ContactName__c=UserInfo.getUserId();
        supportobj.Contact_No__c='9246263254';
        supportobj.Description__c='Test description';
        insert supportobj;
        Projectctrl.createProject(supportobj.id);
        
    }
}






Friday, September 12, 2014

Pass value from visualforce page to controller

Pass value from visualforce page to controller

The first thing a apex programmer wants to know is: how do we communicate between visual force page and  controller. How to pass parameters from a visualforce page to a controller class ?

Lets develop a example that will capture a input in the visualforce page and pass the input value to the controller.


Visualforce Page:

<apex:page controller="passparamController">
    <!-- Pass parameters from visualforce page to controller -->
    <apex:form >
            <apex:pageblock >
                  Input Here <apex:inputText value="{!myinput}"/>
                 <apex:commandButton value="Submit" reRender="outputID" action="{!MyMethode}"/>
            </apex:pageblock>
            <apex:pageblock >
                 <b>Output here = </b><apex:outputText value="{!myoutput}" id="outputID">
                 </apex:outputText>
            </apex:pageblock>
    </apex:form>
</apex:page>


Controller

Public with sharing class passparamController {
  Public string myInput{get;set;}
  Public string myoutput{get;set;}
   
  Public void MyMethode(){
   myoutput = myInput ;
  }
}




In this example,
your {get;set} variable is binded to your input text box which makes it possible to get the value in the controller and also vice versa.

Thus when you press button the input value is passed on to controller.
<apex:inputText value="{!myinput}"/> your input text box is bind to the variable myinput string which is defined as get;set;

When the method is called from the submit button this value from myinput string is assigned to the myoutput string. This is proved when your input value is displayed in output section.

Note: Whenever we have any component wherein we want to input a value it is necessary that that component is enclosed between <apex:form>






Thursday, September 11, 2014

salesforce validation in trigger

salesforce validation in trigger

Salesforce provides validation rules in configuration for standard as well as custom objects. Validation rule for standard object can be written by navigating to following:
set up --> customize --> standard object name --> validation rule

similarly for custom object you can write validation rule by navigating to following:
set up --> create --> objects --> click on the custom object --> scroll down and click on new(next to validation Rules)

Although, you can write validation using simple configuration, sometimes your requirements may not be fullfilled using validation rule especially when your validation criteria is bit complex or need querying in database to check previously created data. In such a case you can write your logic in trigger.

Lets write down a very basic trigger that will throw a validation errror message.

Scenario : Show error message on account if annual revenue is less than 2000.

The error message can be shown using adderror method as shown in the example below:

trigger validation_using_Trigger on Account (before insert, before update) {
 for(Account acc:trigger.new){
    if(acc.AnnualRevenue < 2000){
       acc.adderror('Annual revenue cannot be less than 2000');
    }
 }
}


Above trigger will show error message at the top of the page. You can also display your message at a particular field, you only have to mention the field name in the adderror method as in the below example:

trigger validation_using_Trigger on Account (before insert, before update) {
 for(Account acc:trigger.new){
    if(acc.AnnualRevenue < 2000){
       acc.AnnualRevenue.adderror('Annual revenue cannot be less than 2000');
    }
 }
}

Above triggers will also throw validation errors while inserting/updating records using data loader. 

While writing validation you have to make sure that your trigger is bulkified; that is you are properly iterating over for loop(trigger.new)

Also your trigger should run over before insert and before update contexts as you want the message be displayed before the record is created or updated. 

Also the adderror method should always be written in the trigger new context. Trigger will not show error message if you are iterating over some other collection which is not trigger.new 




Wednesday, September 10, 2014

Data import from csv using Visualforce page

Data import from csv using Visualforce page 

Here is a example to read a csv file and display it in a pageblocktable.

Following example reads a csv file having account records in it and displays them in a table when "Read csv" button is pressed.

Csv file format used in this example:





Visualforce Page:

<apex:page controller="csvFileReaderController">
    <apex:form >  <!-- csv reader demo -->
        <apex:pageBlock >
            <apex:panelGrid columns="2" >
                  <apex:inputFile value="{!csvFileBody}"  filename="{!csvAsString}"/>
                  <apex:commandButton value="Read csv" action="{!readcsvFile}"/>
            </apex:panelGrid>
        </apex:pageBlock>
        <apex:pageBlock >
           <apex:pageblocktable value="{!sObjectList}" var="rec">
              <apex:column value="{!rec.name}" />
              <apex:column value="{!rec.AccountNumber}" />
              <apex:column value="{!rec.Accountsource}" />
              <apex:column value="{!rec.Type}" />
              <apex:column value="{!rec.Website}" />
        </apex:pageblocktable>
     </apex:pageBlock>
   </apex:form>
</apex:page>

Controller Class:

Public with sharing class csvFileReaderController {
public Blob csvFileBody{get;set;}
Public string csvAsString{get;set;}
Public String[] csvfilelines{get;set;}
Public String[] inputvalues{get;set;}
Public List<string> fieldList{get;set;}
Public List<account> sObjectList{get;set;}
  public csvFileReaderController(){
    csvfilelines = new String[]{};
    fieldList = New List<string>();
    sObjectList = New List<sObject>();
  }

  Public void readcsvFile(){
       csvAsString = csvFileBody.toString();
       csvfilelines = csvAsString.split('\n');
       inputvalues = new String[]{};
       for(string st:csvfilelines[0].split(','))
           fieldList.add(st);  
       
       for(Integer i=1;i<csvfilelines.size();i++){
           Account accRec = new Account() ;
           string[] csvRecordData = csvfilelines[i].split(',');
           accRec.name = csvRecordData[0] ;            
           accRec.accountnumber = csvRecordData[1];
           accRec.Type = csvRecordData[2];
           accRec.website = csvRecordData[3];
           accRec.AccountSource = csvRecordData[4];                                                                              
           sObjectList.add(accRec);  
       }
  }
}

Output :







Tuesday, September 9, 2014

Custom clone button in salesforce

Custom clone button in salesforce 

Salesforce provides Clone functionality for some standard objects(Standard Clone button),
However some standard objects do not have this button. For this purpose of cloning we will need to create custom button that will perform the functionality of cloning.

This cloning functionality can be achieved by writing a javascript for this custom button.

As an example lets create a custom button "Clone" on account that will clone the record.

Simply override your custom button "Clone" with the following java script and you will have your custom Clone button that functions exactly like standard clone button

{!REQUIRESCRIPT("/soap/ajax/22.0/connection.js")} 
window.parent.location.href="/{!Account.Id}/e?&deepclone=1&retURL=/{!Account.Id}";

retUrl specifies the location where you want to be on press of back button.






Sunday, September 7, 2014

Approval process using apex.

Approval process using apex

An approval process is an automated process which can be used to approve/reject record updates. A record can be submitted for approval request from related list "Approval History". Once a records is submitted it goes for approval to a specified approver. This is a manual process where in every record should be individually sent for approval.
 How about doing this using apex? Sending the record fro approval from trigger? Salesforec provides number of method for handling approval processes in apex.

Let us submit a record for approval process from trigger in an example below.

Lets say you have a approval process named "Account Owner Approval". You can create a approval process by navigating to following:

set up --> create --> approval process 




Trigger to submit a account record for approval if its annual revenue is less then 2000

trigger Call_AprovalProcess_In_Trigger on Account (before insert, before update) {
 for(Account acc:trigger.new){
    if(acc.AnnualRevenue < 2000){
       approval.ProcessSubmitRequest aprlPrcs = new Approval.ProcessSubmitRequest();     
       aprlPrcs .setComments('Submitting record for approval.');
       aprlPrcs.setObjectId(acc.id);
       approval.ProcessResult result = Approval.process(aprlPrcs);
    }
 }
}







Saturday, September 6, 2014

Javascript validation in visualforce page?

Javascript validation in visualforce page?


Using java script makes it easy to show validation messages as pop ups in a visualforce page. We can call java script function to validate the Input value and subsequently show a pop up message to indicate to the user. 

Following visualforce page uses java script to check if the user had typed Expected price after submit button is pressed.

Visualforce Page:

<!-- Using java script for validation in a visualforce page -->
<apex:page standardcontroller="Account">
  <apex:form >
        <apex:pageBlock >
           Expected price  : <apex:inputText id="inptpriceID"/>
                       <apex:commandButton onclick="validateFunction('{!$Component.inptpriceID}')" value=" Submit Price"/>
        </apex:pageBlock>
  </apex:form>
  
  <!-- Java script starts Here -->
  <script>
   function validateFunction(amountinputID){
       var inputAmount = document.getElementById(amountinputID).value;
         if(inputAmount == ''){
            alert('Please enter amount before submitting price');
         } 
  }
  </script> 
 <!-- java script ends here -->  
</apex:page> 


validateFunction receives html id of the inputtext (Expected price) and from this id checks whether any input was provided, if there was no input then a alert pop is shown.

output:
















Friday, September 5, 2014

What is action support salesforce?

What is action support salesforce?


Action support component adds AJAX support to another component, this allows the component to call a controller method when a particular event occurs(for example onlcik, onblur etc). It also allows to rerender,rendere page sections as desired.

In the following example a controller method is called when you click within a textbox using actionsuppot component.

Controller :


Public with sharing class DemoController {
Public String outValueSecond{get;set;}
Public String outvalue{get;set;}
Public boolean flag{get;set;}
  Public DemoController(){
     outvalue = 'Before Value';
     outValueSecond = 'before value set in constructor';
  }
   
  Public void DemoMethod(){
   outValueSecond = 'After value set in controller method. This method is called using action support added to inputtext compoennt';
  }
}

Visualforce Page: 


<apex:page controller="DemoController">
   <apex:form >
       <apex:pageBlock >
             Click Inside this block <apex:inputtext >
            <apex:actionSupport event="onclick" action="{!DemoMethod}" rerender="pgblck"/>
            </apex:inputtext>  
       </apex:pageBlock>
       <apex:pageblock id="pgblck">
             <apex:outputText value="{!outValueSecond }"/>
       </apex:pageblock>
   </apex:form>
</apex:page>


In this example initially the lower pageblock has a value that is set in constructor, but when the mouse is clicked in the text box the controller method is called which changes the value of the variable that is displayed in the lower pageblock. The controller is called by using action support for the inputtext. The action support also rerenders the lower page block which refreshes the lower block and hence shows the new value set in controller method.











Thursday, September 4, 2014

what is record is read-only trigger?

what is record is read-only trigger?

This post is regarding a error that we get because of trigger. "execution of AfterUpdate caused by: System.FinalException: Record is read-only"
This kind of error occurs if you try to update lists/record which are/is read only in the trigger execution. For example, trigger.new and trigger.old are both read only lists and cannot be applied with a DML operation.

Say if you write Update trigger.new; in your trigger you will get the above mentioned error.
A field value of object can be changed using trigger.new but only in case of before triggers. But in case of after triggers changing the values of the records in trigger.new context will throw exception as "Record is read only"
Example:

trigger mytrigger on account(before insert,before update){
  for(account ac:trigger.new){
      ac.name ='new name';
  }
}
Above code will update the names of the records present in trigger.new list. But, the below code will throw run time exception "Record is read only".
trigger mytrigger on account(after insert,after update){
  for(account ac:trigger.new){
      ac.name ='new name';
  }
}
Also trigger.old will always be read only no matter where you use it either before trigger or after trigger.
That is both the below codes will throw run time exception as trigger.old is read only
trigger mytrigger on account(after insert,after update){
  for(account ac:trigger.old){
      ac.name ='new name';
  }
}
trigger mytrigger on account(before insert,before update){
  for(account ac:trigger.old){
      ac.name ='new name';
  }
}
Note:
1. Trigger.new and trigger.old are read only
2. An object can change its own field values only in before trigger: trigger.new
3. In all cases other than mentioned in point 2; fields values cannot be changed in trigger.new and would cause run time exception "record is read only"





Wednesday, September 3, 2014

What is actionpoller in visualforce?

What is actionpoller in visualforce?


Action poller acts as a timer in visualforce page. It is used to send an AJAX request to the server depending on the time interval (time interval has to be specified or else it defaults to 60 seconds).

In the action attribute a controller method gets called. The method gets called with a frequency defined by the interval attribute which has to be greater than 5 seconds.

In the following example action poller calls the method "CounterMethod" every 5 seconds where the variable "seconds" counter is updated. Rerender attribute refreshes the page block hence showing the updated value of variable "seconds".

Controller Class:
Public with sharing class actionpollerDemoController {
Public  Integer seconds{get;set;}
  Public actionpollerDemoController(){
   seconds = 0;
  }
  Public void CounterMethod(){
    seconds = seconds + 5;
  }
}

Visualforce Page:

<apex:page controller="actionpollerDemoController">
    <apex:form >
        <apex:pageBlock id="pgplck">
              <apex:actionPoller action="{!CounterMethod}" reRender="pgplck" interval="5"/>
                      {!seconds } seconds since the action poller was called !!
         </apex:pageBlock>
      </apex:form>
</apex:page>


Output :

save image


Time out can also be specified as an attribute in action poller. Once the time out point is reached it stops making AJAX callout to the server and controller method is no more called.




How to writeTest class for batch apex in salesforce?

How to write Test class for batch apex in salesforce?


Let us learn to write a test class that covers a batch apex class. Nothing better than learning from a working example.
Here is a test class for a batch apex class that updates account records that are passed through a select query.
Batch apex clas
global class BatchProcessAccount implements Database.Batchable<sObject>{
 String query;
global Database.querylocator start(Database.BatchableContext BC){
        Query = 'Select id,name,AccountNumber,type from account';
        return Database.getQueryLocator(query);
 }
 global void execute(Database.BatchableContext BC, List<account> scope){
       List<Account> AccountList = new List<Account>();
       for(account acc : scope){
           acc.AccountNumber= '8888';
           AccountList.add(acc);
       }
       update AccountList ;
    }
   global void finish(Database.BatchableContext BC){
    }
}
Test class for above batch apex class
@isTest
private class BatchProcessAccount_Test {
     
static testMethod void BatchProcessAccount_TestMethod (){
     Profile prof = [select id from profile where name='system Administrator'];
     User usr = new User(alias = 'usr', email='us.name@vmail.com',
                emailencodingkey='UTF-8', lastname='lstname',
                timezonesidkey='America/Los_Angeles',
                languagelocalekey='en_US',
                localesidkey='en_US', profileid = prof.Id,
                username='testuser128@testorg.com');
                insert usr;
   Account accRec = new Account(name='testName', Ownerid = usr.id);
   insert accRec ;
   Test.StartTest();
   BatchProcessAccount objBatch = new BatchProcessAccount();
   ID batchprocessid = Database.executeBatch(objBatch);
   Test.StopTest();
  }
}



Just create a instance of the batch apex class: BatchProcessAccount objBatch = new BatchProcessAccount();
and then pass the craeted varaible in executebatch method as below:
   ID batchprocessid = Database.executeBatch(objBatch);

 

 
| ,