Monday, February 16, 2015

Restrict Record level Access in Salesforce

There are different approaches available to restrict access at different levels in Salesforce.

In this article we look into options available to restrict record level access in a object.

To restrict access at a record level, first we need to configure Organization-Wide Default (OWD) sharing of the object to 'Private'. This configuration once set, all the records will be private. Other users can't access them. Now, we open access using variety of means, like roles, groups, profiles ,sharing rules and manual sharing.

To configure OWD sharing, follow below steps.
  1. From Setup, click Security Controls > Sharing Settings.
  2. Under Organization Wide-Defaults, click Edit.
  3. Change the picklist next to the 'Custom object' to Private.
  4. Click Save

The check box is 'Grant Access Hierarchy'. If checked, access to a record will be provided to the Owner's top level hierarchy as per roles defined in the Organization.

Let us assume we already have some Roles and Profiles created as per our Org structure.

Now, to assign access to the records, we use 'Sharing Rules'. These are rules we define to provide access to record based on some criteria of data / owner.

We can provide access to a  Role. In some cases, we might need to provide access to multiple people of different Roles and Profiles. In such cases, we can create a User groups and provide access to the group through these rules.

To create a Sharing Rule, follow below steps,

  1. From Setup, click Security Controls > Sharing Settings.
  2. Under 'Custom Object' Sharing Rules, click New.
  3. In the Label field, Rule Nmae, provide relevant name.
  4. For Rule Type, select Based on Criteria.
  5. In Criteria, choose the criteria you are looking for, as a sample selecting the following values:
    • For Field, choose City.
    • For Operator, choose equal to.
    • For the Value type, enter 'Hyderabad'.
  6. For Share With, we have different options i.e. Roles / Groups. Choose Roles and Subordinates and select Warehouse Manager from the picklist.
  7. For Access Level, choose Read/Write.
 Once the rule is saved, a job will be executed to run the rule on the object we created. So, each time you update the rule, it is executed.

Internally, for every object we have 'object__Share' table with corresponding apex modal object. When a Sharing rule is executed, if the criteria is met on a record, corresponding access entries are entered into this table.

Irrespective of rules / criteria if we want to provide access on a record, we can provide through Manual sharing,  by using default 'Sharing' option available on detailed screen



To implement Manual Sharing, follow below steps
  1. Click on the record for which we want to add i.e. open detailed screen
  2. Click on 'Sharing' button available along with other default action buttons
  3. A list with available accesses for the record are displayed. click on 'Add'
  4. A screen to choose User / Role / Group is displayed. 
  5. Select the corresponding people / group to whom we need to provide access and click on Save

In this way we  can restrict access to a Record.

If we need to provide access to a record dynamically based  on a criteria where value and access mappings are dynamic, we can implement the above 'Manual Sharing' option using Apex.

We can create a Custom object to map criteria and corresponding access details. Now, using a trigger on our Object, upon insert or update, we validate the criteria and if true, add record to the 'Object__Share' table through Apex with corresponding details.


 if(/* Condition to validate */)  
       {  
         //If true,   
         TF_Location__Share jobShr = new TF_Location__Share();  
         // Set the ID of record being shared.  
         jobShr.ParentId = record.id;  
         // Set the ID of user or group being granted access.  
         jobShr.UserOrGroupId = '005j000000BYezb';  
         // Set the access level.  
         jobShr.AccessLevel = 'Read';  
         // Set rowCause to 'manual' for manual sharing.  
         // This line can be omitted as 'manual' is the default value for sharing objects.  
         jobShr.RowCause = Schema.TF_Location__Share.RowCause.Manual;  
         // Insert the sharing record and capture the save result.   
         // The false parameter allows for partial processing if multiple records passed into the operation.  
        Database.SaveResult sr = Database.insert(jobShr,false);  
        // Process the save results.  
        if(sr.isSuccess()){  
            // Indicates success  
        }  
       }  


No comments:

Post a Comment