Since Salesforce began to require CRUD / FLS checks as part of the Security Review for AppEchange apps in 2015 there has been a lot of discussions why this cannot be done by the platform and how this can be solved in an easy and reliant way.
Most bigger ISVs since the use a mix of different frameworks and libraries among which the Financial Force Apex Commons (a.k.a. fflib) and Patron DML Manager are the most successful.
The fflib safeguards Object and field level queries in its Selector classes and its Query Factory:
public List<Account> selectById(Set<Id> ids) {
return Database.query( newQueryFactory()
.assertIsAccessible(true)
.setEnforceFLS(true)
.setCondition('Id IN :ids').toSOQL() );
}
The DML Manager enforces C(R)UD safety by wrapping the native DML operations:
List<Contact> contacts = [SELECT Id, FirstName, LastName FROM Contact];
...
DMLManager.updateAsUser(contacts);
But as always all of this has some drawbacks (e.g. limit-intense and cluttered code) so that many developers who had not to go through Security Review skipped using them.
Apex also now has some new features to better handle this:
- the
WITH_SECURITY_ENFORCED
SOQL keyword - the
stripInaccessibleFields()
method on SObjects
So how would YOU enforce CRUD and FLS if you could start from scratch and your goals are:
- small footprint library (amount of classes + concepts)
- clean and lean API (doesn't add much clutter to code)
- has proven to go smoothly through security review
- efficient regarding CPU and other Governor limitations
Note: I will leave this question open for a long time to invite many to add, vote and comment on answers by others.
WITH SECURITY_ENFORCED
norSecurity.stripInaccessible()
is GA, with one release to go in CY19. So they can't yet be used for an app that "has to pass Security Review in 2019". But they will definitely make things a lot easier when they are GA!