Sharing Keyword in Salesforce

Background:- Before I start with Sharing keyword and its importance, I would like to discuss in brief about UserMode and SystemMode. As main reason for using sharing keyword depends on the usage of Usermode and SystemMode.

UserMode:- User mode is nothing but apex code running by respecting user's permissions and sharing of records. For example, logged in user does not have create permission and so he/she is not able to create a record.In Salesforce, only standard controllers and anonymous blocks like developer console run in user mode.

SystemMode:-System mode is nothing but running apex code by ignoring user's permissions. For example, logged in user does not have create permission but he/she is able to create a record. We can think of SystemMode as GodMode, Apex code has access to all objects and fields— object permissions, field-level security, sharing rules aren't applied for the current user. This is to ensure that code won’t fail to run because of hidden fields or objects for a user.In Salesforce, all apex code run in system mode. It ignores user's permissions. Only exception is anonymous blocks like developer console and standard controllers. Even runAs() method doesn't enforce user permissions or field-level permissions, it only enforces record sharing.

Why Sharing:- There is a reason I discussed SystemMode and UserMode before starting with Sharing keyword. As we can see that all apex runs in SystemMode, Which means code has access to everything whether the current user has access or not. So why do we really use sharing keyword. The reason to add with Sharing keyword in apex is to enforce Record Level Security thats it. As per salesforce definition is sharing keywords on a class to specify whether sharing rules must be enforced. Sharing Rules comes under Record Level Security only.

UseCase:- If we have 1000 Accounts in salesforce, And there is one user A who own 100 records and doesnt have access to other 900 accounts what will be the behaviour while using with sharing keyword.

By defualt apex runs in system mode so even though User A doesnt have access to 900 records he will be able to the result as 1000.

         public DefaultClass(){                                  
                                  public void queryAccount(){

                                          Integer i= [Select Count(ID) from Account];
                                  }
                 }

IF we now apply with sharing keyword User A will only see the records he own or he has access to via sharing rules, which in our case is 100. SO the result in this case is 100 only.

                     Public with Sharing sharingClass(){          
                                  public void queryAccount(){

                                          Integer i= [Select Count(ID) from Account];
                                 }


So to hide sensitive data that users dont have access to when coming from apex class we have to define the sharing keyword.

Without Sharing:- Without sharing works similar to SystemMode. No sharing rules are enfored. So if we take our above use case the result will be 1000 only.

                    Public without Sharing withoutsharingClass(){          
                                  public static void queryAccount(){

                                          Integer i= [Select Count(ID) from Account];
                                 }


This is confusing , As we can see the same result is coming if our class has no sharing keyword with it and our class has without sharing keyword with it. This makes no sense right. Than why we will call without sharing explicitly if defaultclass is doing the job.

Without sharing keyword is used whenever we have a class that is defined with Sharing keyword and when we want to explicitly turn sharing rule enforcement by calling a method of another class that is defined as without sharing. this will make more sense with example.

So we have a class 
      
                Public with Sharing AccountCount(){          
                                  public void AccountsData(){
                                 
                                        withoutsharingClass.queryAccount();
                                          
                                 }

As we have noticed that our AccountCount class is have with Sharing keyword in it and inside method AccountsData we are calling our withoutSharingClass queryAccount method. As we want correct count of Accounts in our system, which can only provide correct result if our query is running in system mode. And thats whats happening here because we have defined withoutSharingClass as without Sharing it will enfore sharing rules and we will get result of 1000 Accounts.

But if we would have chosed default class option than this result would have been different.

                Public with Sharing AccountCount(){          
                                  public void AccountsData(){
                                 
                                        DefaultClass.queryAccount();
                                          
                                 }

The result here will be 100 and reason for that is whenever we call a default class(with no sharing keyword) from a class that is having with Sharing keyword. Automatically Sharing rules are enforced. I hope this provides better understanding of without sharing and default class difference.

Inherited Sharing:- If you specify inherited sharing Keyword on an Apex class,  which allows the class to run in the sharing mode of the class that called it. Using inherited sharing enables you to pass security review and ensure that your privileged Apex code is not used in unexpected or insecure ways.

An Apex class with inherited sharing runs as with sharing when used as a Visualforce page controller, Apex REST service, or an entry point to an Apex transaction.
An Apex class with Inherited Sharing is being called from some other class which is having without sharing setting, then it will run in without sharing mode.

Considerations while using Sharing or without Sharing Keyword:-

The sharing settings of the class in which the method is defined is applied,not of the class where the method is called. So if there is a method which is defined in a Class which has with sharing enabled but the method is called in a class which doesn’t have sharing(without sharing) enabled,the method will execute with sharing rules enforced.
We can declare inner and outer classes with sharing keyword. The sharing setting will be applied to all the code present in the class including intialization code, methods and constructors.
Inner classes do not inherit the sharing setting from the outer class. Classes inherit sharing setting from their parent class when one class extends from another class

Comments

Popular posts from this blog

Set Field-Level Security for a Field on Permission Sets Instead of Profiles (Generally Available)

Einstein GPT - Generative Responses : Summer'23 Salesforce Release

Program Assignment Invocable Action : Summer'23 Salesforce Release