Sharing rules enforcement

As discussed in the previous chapter, by default, Apex code runs in system mode, meaning no sharing rules are enforced. However, business logic behavior should, in general, honor sharing rules. To avoid sharing information to which the user does not have access, sharing rule enforcement must be a concern of the Service layer.

The Salesforce security review requires Apex controller class entry points to honor this, although your Service layer will be called by these classes and thus could inherit this context. Keep in mind that your Service layer is effectively an entry point for other points of access and integrations (as we will explore in a later chapter and throughout the book).

Thus, the default concern of the Service layer should be to enforce sharing rules. Code implemented within the Service layer or called by it should inherit this using the inherited sharing keyword. Code should only be elevated to running in a context where sharing rules are ignored when required, otherwise known as the without sharing context. This would be in cases where the service is working on records on behalf of the user. For example, a service might calculate or summarize some race data but some of the raw race data records (from other races) may not be visible to the user.

To enforce sharing rules by default within a Service layer, the with sharing keyword is used on the class definition, as follows:

public with sharing class RaceService

Other Apex classes you create, including those we will go on to discuss around Selector and Domain patterns, should use the inherited sharing modifier such that they inherit the context—this allows them to be reused in either context more easily.

You should aim to use one of the three sharing keywords in each class you create. This declares the intent of the code within the class with respect to security. The absence of this can give rise to ambiguity or cause delays in your Salesforce security review process as the source code scanner or the person reviewing your code has to raise failures to be resolved. This chapter and the next will offer further guidelines on this as well.

If a without sharing context is needed, a private inner class approach, as shown in the following example, can be used to temporarily elevate the execution context to process queries or DML operations in this mode:

// Class used by the Service layer 
public inherited sharing class SomeOtherClass { 
 
  // This method inherits sharing context from Service 
  public static void someMethod {  
    // Do some work in inherited context 
    // ... 
 
    // Need to do some queries or updates in elevated context 
    new ElevatedContext().restOfTheWork(workToDo); 
  } 
 
  private void restOfTheWork(List<SomeWork>workToDo) { 
    // Additional work performed by this class 
    // ... 
  } 
 
  private without sharing class ElevatedContext { 
    public void restOfTheWork(List<SomeWork>workToDo) { 
      // Do some work in a elevated (without sharing) context 
      SomeOtherClass.restOfWork(workToDo); 
      } 
  } 
} 

Note that you can consider making the ability to run logic a parameter of your Service layer if you feel certain callers will want to disable this enforcement. The preceding code sample could be adapted to conditionally execute the restOfWork method directly or via the ElevatedContext inner class in this case.

Object- and field-level security are also important considerations when deciding when to enforce and when not. Later chapters that focus more on the Domain and Selector patterns will discuss this topic further.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.22.135