GDPR and Apex Code, should you care?

In short: YES, a lot.

That’s it, post done.
Thank you for reading.

Hold on, not so fast…

Since the GDPR regulation became effective, there has been madness around it. It changed the way the private and sensible data should be handled by, introducing numbers of laws around it.
The GDPR is a European regulation, however, Salesforce is a worldwide environment, and that means that your software could be affected and needs to comply with the GDPR regulations.

Not convinced yet why should you care? Ok, let get more technical.

The declarative features of Salesforce enforce by default CRUD and FLS permissions. That means that a fellow #AwesomeAdmin can lock it down all the personal or sensitive data that a user shouldn’t see with few clicks.

However. Apex code runs typically in System mode, that means that CRUD and FLS are not enforced automatically.
You have to enforce them with some extra code.

Let’s see a real-life example:

You have been hired from Houdi-me. Houde-me sales mind cracking puzzles. Some of those puzzles are so hard to solve that they offer a phone help desk to give some hints to the customers when they are stuck and cannot get to the solution.
The Call centre operator needs to know the name of the customer and what puzzle the customer is struggling with but doesn’t need to see the email address or the phone number of the customer. You can remove access from the profile of the CallCentre operator easily. No code required.

However, the email is used from Houdi-me to promote new puzzles to the customers, but not all the customers want that promotional email. To simplify the process, Houdi-me decided to provide a custom button to the Call centre operator to “forget” some data od the customer, even if the user does not have access to that data.

It’s your time to shine. You have to write an extension of the Contact controller to “clean” some data from the record.

public PageReference forget(){
        customer.Email = '';
        update customer;
        PageReference pageRef = new PageReference('/';
       	return pageRef;

And voila’, you have just used the power of Apex to get around the FLS limitation for the Call centre User and cleaned the email without shown the data to the user; GDPR enforced.

At Houdi-me they encourage their customers to spread the love for their puzzles. A Customer can nominate up to three additional email addresses to give access to the help desk to friends or family members to which they have borrowed the puzzle. To manage those relationship-email pairs, Houdi-me will use a custom page and will give access only to selected users of the Call centre, because those are Personal Identifiable Informations.

Even if the fields have been looked down for the Call centre user, you cannot assume that the field would be protected from indiscreet eyes.

In the Visualforce page, the fields need to be displayed using the object fields using the standard object notation.

<apex:OutputText value="{!customer.FirstFriendEmail__c}" />

Using a similar notation the FLS is enforced, and the data will be concealed to who won’t have the right to see it.

Be careful about using custom getters to display the data like this.

<apex:OutputText value="{!FirstFriendEmail}" />

populated with Apex code like this

public String getFirstFriendEmail(){
    return customer.FirstFriendEmail__c; 

Because in this case, you are introducing a CRUD & FLS Violation and if a standard Call centre user would gain access to the page it will see data that is not supposed to see. GDPR problem. In fact, the custom getter is treated as a simple string, not as data from the object.

The CRUD & FLS violation should be prevented on data update as well.
For this reason, the DescribeSObjectResult class includes some helper functions to check the user’s accessibility to the data.

  • IsCreateable()
  • IsAccessible()
  • IsUpdateable()
  • IsDeleteable()

In our case

//Let’s assume we have fetched contact “c” from a SOQL query
if (!Schema.sObjectType.Contact.fields.FirstFriendEmail__c.isUpdateable()){
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'Error: Insufficient Access'));
    return null;
update c;

would be used to update the customer record only when the user has access to the field, and degrade gracefully in case the access to the field is not granted.

But another question is still open:
Is the user allowed to access the record?

Houdi-me has two main call centres, and they have their pool of customers to look after. One call centre user shouldn’t be able to see the data of a customer served from the other call centre. The Sharing architecture of Salesforce allows to achieve this quite quickly, but Apex doesn’t enforce the sharing rules unless explicitly said so.
The with sharing keyword used in the class declaration enforces the Sharing in the methods of the class.

Apex leave you the option to chose whether or not enforce the sharing rules in your code:

public with sharing MyClassWithSharing{}
public without sharing MyClassWithout{}
public MyClass{}

the first class will enforce the sharing the second Class will skip the sharing and the third could depend from the caller or whether the class implements an interface or extends another class and what type of sharing the caller or the parent class enforces.

To a more exhaustive explanation of the sharing have a look at the SF documentation.

As you can see Apex a Visualforce leave to you the freedom and the power to control who should access the data, and is this flexibility that let you implement the right level of access to comply with the GDPR regulation.



GDPR regulation

Trailhead Data Leak Prevention Module