6

I'm going through CRUD and Field-Level Security (FLS) from Lightning Components Developer Guide, and the following code for Field-Level Security validation doesn't make any sense for me in terms of good development practices:

// Obtain the field name/token map for the Expense object
Map<String,Schema.SObjectField> m = Schema.SObjectType.ns__Expense__c.fields.getMap();

for (String fieldToCheck : expenseAccessFields) {

    // Check if the user has access to view field
    if (!m.get(fieldToCheck).getDescribe().isAccessible()) {

        // Pass error to client
        throw new System.NoAccessException()

       // Suppress editor logs
       return null;
    }
}

Isn't an ultimate goal is to hide ONLY the fields that the current user shouldn't have access to? And another question - what do you use to control Field-Level Security [in Apex for Lightning] as the most efficient/convenient method?

2
  • Definitely not the way I would go, they are going through the lazy mode haha. In their example they are checking for the whole object and not only the fields used on the component. I would still want the end user to have access to the page and display at least the fields he has access to. However in terms of development it will be more challenging, that's for sure. 1) build query based on the fields the current has access to. 2) display the fields dynamically in your component based on their accessbility.
    – brovasi
    Commented Jan 25, 2017 at 0:52
  • @CloudNinja This is exactly what I'm asking - in Visualforce pages this was done automatically, and now it seems like not so trivial task, especially when you are supposed to do CRUD and FLS on everything, as recommended best practice. Was wondering if ppl had developed some techniques since Lightning is being pushed for long enough...
    – o-lexi
    Commented Jan 25, 2017 at 1:11

2 Answers 2

8

Since Winter 20 release, we have Security.stripInaccessible() method which strips the fields that the current user can’t access from query and subquery results.

Since Spring 20 release Security.stripInaccessible() method is Generally Available.

You can use it to remove inaccessible fields from sObjects before a DML operation to avoid exceptions. You can also use the method to sanitize sObjects that have been deserialized from an untrusted source.

For example (taken from apexdocs) the user doesn’t have permission to read the ActualCost field of a Campaign:

List<Campaign> campaigns = new List<Campaign>{
    new Campaign(Name='Campaign1', BudgetedCost=1000, ActualCost=2000),
    new Campaign(Name='Campaign2', BudgetedCost=4000, ActualCost=1500)
};
insert campaigns;
// Strip fields that are not readable
SObjectAccessDecision decision = Security.stripInaccessible(
    AccessType.READABLE,
    [SELECT Name, BudgetedCost, ActualCost FROM Campaign]
);
// Print stripped records
for (SObject strippedCampaign : decision.getRecords()) {
    System.debug(strippedCampaign); // Does not display ActualCost
}
// Print modified indexes
System.debug(decision.getModifiedIndexes());
// Print removed fields
System.debug(decision.getRemovedFields());
//Lines from output log
//|DEBUG|Campaign:{Name=Campaign1, BudgetedCost=1000, Id=701xx00000011nhAAA}
//|DEBUG|Campaign:{Name=Campaign2, BudgetedCost=4000, Id=701xx00000011niAAA}
//|DEBUG|{0, 1}
//|DEBUG|{Campaign={ActualCost}}
2

The ultimate goal depends on the business needs .One of below can be adopted

1.You can collect only those fields that user has and ignore the other fields user does not have access to

2.You can throw exception and asking user to reach out to admin to explicitly assign permission set

To manage CRUD FLS you can use some library to reduce code rewrite

The one that's commonly used and open source is ESAPI

https://code.google.com/archive/p/force-dot-com-esapi/wikis/GettingStarted.wiki

3
  • 2 is what actually thye do in their example, 1 is more preferable, but I'm not so sure how would you (A) do inline SOQL, and (B) how to hide fields in Lightning component that current user can't access? From what I've read about ESAPI, it lets you to "allows apex classes execute statements such as insert object; as if operating in user context.". But this is not what I'm asking.
    – o-lexi
    Commented Jan 25, 2017 at 1:06
  • 1
    ESAPI has built in logic to do all CRUDFLS for you .You use the same logic as in 2 but instead of error you write a dynamic soql with only field that user has access . Commented Jan 25, 2017 at 1:08
  • 5
    It's ok to get dynamically the right SOQL with only the accessible fields, the challenge is how to display that dynamically on the page ? Because you will build the page based on full access. So your method shouldn't return only a list of object but also the list of (not) accessible fields, then on the component you could check if field is accessible then display it, otherwise skip, could probably do it using a wrapper class.
    – brovasi
    Commented Jan 25, 2017 at 1:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .