Tag Archives: SOQL

Enforce Field-Level Security Permissions for SOQL Queries

  • In Spring ’19 Release Salesforce has introduced WITH SECURITY_ENFORCED clause, you can use this to enable checking for field- and object-level security permissions on SOQL SELECT queries, including subqueries and cross-object relationships.
  • Currently if you include a field in a SQOL query (Without WITH SECURITY_ENFORCED Clause) and a user doesn’t have access to that field, the field will be returned and can be used by the code without any exception, but the data to that user should not have access.
  • If you use WITH SECURITY_ENFORCED clause for same SOQL Select query, it will throw exception and no data will be returned.
  • This feature is tailored to Apex developers who have minimal development experience with security and to applications where graceful degradation on permissions errors isn’t required. The WITH SECURITY_ENFORCED clause is only available in Apex.
  • The WITH SECURITY_ENFORCED clause is only available in Apex. Using WITH SECURITY_ENFORCED in Apex classes or triggers with an API version earlier than 45.0 is not recommended.

Example:

If the Contact Email & Phone fields permission is not accessible to the user, it will throw an exception insufficient permissions and no data will return.

SELECT Id, Name, (SELECT Email, Phone FROM Contacts) FROM Account WITH SECURITY_ENFORCED

If the Account Website filed permission is not accessible to the user, it will throw an exception insufficient permissions and no data will return.

SELECT Id, Name, Website FROM Account WITH SECURITY_ENFORCED

Check Case Owner is a User or Queue

Check Case Owner in Apex Class.

//Check object Id in Apex 
if(string.valueOf(c.OwnerId).startsWith('005')){
    //Owner is User       
}

if(string.valueOf(c.OwnerId).startsWith('00G')){
    //Owner is Queue
}

Check Case Owner in Apex Trigger.

//In Apex Trigger
for (Case objCase : Trigger.new) { 
    If (objCase.OwnerID.getsobjecttype() == User.sobjecttype) {
        /*Code if Owner is User*/
    }
    else{
        /*Code if Owner is Queue*/ 
    }
}

Check Case Owner by SOQL query.

//By Query Owner.Type Field
List<Case> caseList = [SELECT Id, CaseNumber, OwnerId, Owner.Name, Owner.Type FROM Case];

for (Case objCase : caseList){
    If (objCase.Owner.Type == User.sobjecttype) {
        /*Code if Owner is User*/
    }
    else{
        /*Code if Owner is Queue*/ 
    }
}

Check Case Owner in Process Builder.

//Check in Process Builder
BEGINS([Case].OwnerId, "005") //Check Owner is User
BEGINS([Case].OwnerId, "00G") //Check Owner is Queue

Display Inner SOQL Query Data in Lightning Component

Apex Controller:
Create below apex controller to get the inner SOQL query data.

public with sharing class AuraSampleController{
    @AuraEnabled
    public static List<Account> getAccounts() {
        List <Account> accList = [SELECT Name, Type, Industry, (SELECT FirstName, LastName From contacts) From Account LIMIT 5];
        return accList;
    }
}

Sample Lightning Component:
Create below lightning component Sample.cmp for display the inner SOQL query data on component.

<!--Sample.cmp-->
<aura:component controller="AuraSampleController">
    <aura:attribute name="accList" type="Account[]" description="List of Accounts with respective Contacts"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <ul>
        <aura:iteration items="{!v.accList}" var="acc">
            <li type="dice">Account Name : {!acc.Name}</li>
            <ul>
                <aura:iteration items="{!acc.Contacts}" var="con" indexVar="index">
                    <li>Contact Name : {!con.FirstName} &nbsp; {!con.LastName}</li>
                </aura:iteration>
            </ul>
            <hr/>
        </aura:iteration>
    </ul>
</aura:component>

Sample Lightning Component JS Controller:
Create below JavaScript Controller for above Sample.cmp component.

({
    doInit: function(component, event, helper) {
        //Call apex class method
        var action = component.get('c.getAccounts');
        action.setCallback(this, function(response) {
            //Get state of response
            var state = response.getState();
            if (state === "SUCCESS") {
                //Set result in accList attribute on component.
                component.set('v.accList', response.getReturnValue());
            }
        });
        $A.enqueueAction(action);
    }
})

Lightning Test App:

<!--Test.app-->
<aura:application extends="force:slds">
    <c:Sample />
</aura:application>

Output: