1

Please help me solving this Issue.

I'm new to the salesforce, I worte an Controller which do get list of objects values from contact, Cases and also inserts New cases and Case comments to, During the submittion of Security review, I got a response stating

Insert: Scanning File: K:........\classes\contact_list_controller.cls 145 insert newcases; 167 insert case_comment;

Select: Scanning File: K:.......\classes\contact_list_controller.cls 121 detailscase=[select casenumber,Description,isclosed, isdeleted,priority,status,subject,type,reason,origin,CreatedDate from case where casenumber= :Case_ID];

public with sharing class contact_list_controller {

//variable Initialization 

  // URL parameter variables
  public String user_contact_EmailID{get; set;}
  public String contact_guid{get; set;}

  //variable for storing the date retrived from the Database
  public List<Contact> contacts;
  public List<Case> cases;
  public String Case_ID;

  // flags for internal popup
  public boolean displayPopup {get;set;}
  public boolean case_comment_popup {get; set;}

  // variable for submitting the data into the salesforce Database
  public Case newcases {get; set;} 
  public Case detailsCase{get;set;}
  public CaseComment case_comment {get; set;}


// Retriving the details for the standard Object (contact) 

  public contact_list_controller(ApexPages.StandardController controller) {
     contact_guid = ApexPages.currentPage().getParameters().get('guid') ;
     user_contact_EmailID = ApexPages.currentPage().getParameters().get('contid');
     contacts = [Select ID,name,phone,mobilephone,fax,email,birthdate,mailingcity,mailingstate,mailingcountry,homephone,PhotoUrl,Lastname from contact where email = :user_contact_EmailID]; 
     newcases = new Case();
     case_comment = new CaseComment(); 
     detailsCase = new Case();  
  }

  // function for storing the Contact details in contacts variable

  public List<Contact> getContacts() {
    return contacts;
  }

  // Code for retriving the details of the Cases and checking the accessible for the user  

  public List<Case> getCases(){
   if(cases == null) {
      String [] caseUpdateFields = new String [] {'casenumber','Description','isclosed','isdeleted','priority','status','subject','type','reason','origin','CreatedDate'};

      // Obtaining the field name/token map for the case object
      Map<String,Schema.SObjectField> caseAccessable = Schema.SObjectType.Case.fields.getMap();
      for (String fieldToCheck : caseUpdateFields) {
        // Check if the user has create access on the each field
        if (!caseAccessable.get(fieldToCheck).getDescribe().isAccessible()) {
          return null;
        }
      }
        cases=[Select casenumber,Description,isclosed, isdeleted,priority,status,subject,type,reason,origin,CreatedDate from Case where case.contactid =: contacts[0].ID ORDER BY casenumber DESC limit 5];
    }
  return cases;
  } 

  public void case_detail(){
    try{
        Case_ID = Apexpages.currentPage().getParameters().get('myParam');

        String [] singleCaseDetailFields = new String [] {'casenumber','Description','isclosed','isdeleted','priority','status','subject','type','reason','origin','CreatedDate'};
          // Obtaining the field name/token map for the case object
        Map<String,Schema.SObjectField> singleCaseDetailAccessable = Schema.SObjectType.Case.fields.getMap();
        for (String singleCaseDetailfieldToCheck : singleCaseDetailFields) {
            // Check if the user has create access on the each field
            if (!singleCaseDetailAccessable.get(singleCaseDetailfieldToCheck).getDescribe().isAccessible() ) {
            }
        }
    if(Case_ID !=null){
        detailscase=[select casenumber,Description,isclosed,isdeleted,priority,status,subject,type,reason,origin,CreatedDate from case where casenumber= :Case_ID];
      }
    }
    catch (Exception ex) {
      System.debug(LoggingLevel.Error, 'contact_list_controller.case_detail() Exception: ' + ex);
    }
    finally{
      displayPopup = true;
      detailsCase = new Case(); 
    }
  }

  // Function for inserting the newcases
  public void Save(){
    try{
      String [] newCaseCreateFields = new String [] {'Priority','Origin','Type','Status','reason','subject','Description'};
  // Obtaining the field name/token map for the case object
        Map<String,Schema.SObjectField> NewCaseCreateisCreateable = Schema.SObjectType.Case.fields.getMap();
        for (String NewCaseCreatefieldToCheck : newCaseCreateFields) {
            // Check if the user has create access on the each field
            if (!NewCaseCreateisCreateable.get(NewCaseCreatefieldToCheck).getDescribe().isCreateable() ) {

            }
        }
      newcases.contactid = contacts[0].Id; 
      insert newcases;      
    } 
    catch (Exception ex) {
      System.debug(LoggingLevel.Error, 'contact_list_controller.Save() Exception: ' + ex);
    }
    finally{
      displayPopup=false;
    }    
  }

// Function for adding the comment for each single case using the CaseID
  public void save_casecomment(){
    try{ 
      String [] newCaseCommentCreateFields = new String [] {'parentid','commentbody'};
  // Obtaining the field name/token map for the case object
        Map<String,Schema.SObjectField>newCaseCommentCreateisCreateable = Schema.SObjectType.CaseComment.fields.getMap();
        for (String newCaseCommentCreatefieldToCheck : newCaseCommentCreateFields) {
            // Check if the user has create access on the each field
            if (!newCaseCommentCreateisCreateable.get(newCaseCommentCreatefieldToCheck).getDescribe().isCreateable() ) {
            }
        } 
      case_comment.parentid = [Select ID from Case where casenumber= :Case_ID].Id;
      insert case_comment;
    }
    catch (Exception ex) {
      System.debug(LoggingLevel.Error, ' save_casecomment() Exception: ' + ex);
    }
    finally{
      case_comment_popup = false;
      case_comment = new CaseComment();
    }
  } 



  // Functions for Closing the popup inside the chatpopup page
  // function to close the popup    
  public void ClosePopup(){
    displayPopup=false;
  } 
  //function to close casecomment
  public void Casecomment_close(){
    case_comment_popup = false;
  }

  // function to show the popup    
  public void showPopup() {        
    displayPopup = true;     
  }  

  public void casecomment(){
    case_comment_popup = true;   
  }                      
}

Test method class

@isTest
public class ContactlistController {      
  static testMethod void testContactList (){
    List<Contact> contacts = new List<Contact>();
    for (Integer count = 0; count < 2; count++) {
        contacts.add(new Contact (FirstName = 'John'+count, LastName ='Doe'+count));
    }
    insert contacts;
    String contactId = contacts[0].Id;

    List<Case> cases = new List<Case>();
    for (Integer count = 0; count < 2; count++) {  
        cases.add(new Case (Description = 'Testing'+count, reason ='Testing'+count));
    }
    cases[0].contactid = contactId;
    cases[1].contactid = contactId;
    insert cases;
    String caseId = cases[0].Id;

    CaseComment case_comment =(new CaseComment (commentbody = 'Testing'));
    case_comment.parentid = caseId;
    insert case_comment;
    if(caseId != null){
    List<Case> detailscase=[select casenumber,Description,isclosed, isdeleted,priority,status,subject,type,reason,origin,CreatedDate from case where casenumber= :caseId];
    }
    contact_list_controller cc = new contact_list_controller(new ApexPages.StandardController(contacts[0]));
        cc.getContacts();
        cc.ClosePopup();
        cc.Casecomment_close();
        cc.showPopup();
        cc.casecomment();
        cc.getCases();
        cc.getUserdevice();
        cc.save();
        cc.case_detail();
        cc.chatdetaillist();    
        cc.save_casecomment();
  } 
}
  • 1
    Chandu, do yo know to check CRUD and FLS in any other piece of code ? If not .. then your question isn't specific to this code and I would recommend you take it out and rephrase the question to your real question: "How do I check CRUC and FLS in apex ?". – Samuel De Rycke Feb 12 '16 at 10:24
  • @SamuelDeRycke ,Thanks for the suggestion, I have changed the Question content. Can you please help me solving this, because I'm trying to solve this issue from past 2 weeks and I'm not able to figure out to fix it. – Chandu Feb 12 '16 at 11:28
5

Please refer to this knowledge article.

Basically you just need to add some checks like

    if (!Schema.sObjectType.Contact.fields.Name.isAccessible()){
      return '';
    }

or

if (!Schema.sObjectType.Contact.fields.Name.isUpdateable()){
  return null;
}

For dynamic check you could use Describe functionality.

Basically you need to use several methods from DescribeFieldResult class and from DescribeSObjectResult class.

DescribeFieldResult class

  • isAccessible()

  • isCreateable()

  • isUpdateable()

DescribeSObjectResult class

  • isAccessible()

  • isCreateable()

  • isDeletable()

  • isMergeable()

  • isUndeletable()

  • isUpdateable()

=================================

In your case, you can do this:

public void Save(){
    try{
        String [] newCaseCreateFields = new String [] {'Priority','Origin','Type','Status','reason','subject','Description'};

        newcases.contactid = contacts[0].Id; 
        if ( !Schema.sObjectType.Case.isCreateable() ) {
            System.debug(LoggingLevel.Error, 'you don\'t have access to create case');
        } else if ( !Schema.sObjectType.Case.fields.ContactId.isUpdateable() ) {
            System.debug(LoggingLevel.Error, 'you don\'t have access to update case ContactId');
        } else {
            insert newcases; 
        }     
    } 
    catch (Exception ex) {
        System.debug(LoggingLevel.Error, 'contact_list_controller.Save() Exception: ' + ex);
    }
    finally{
        displayPopup=false;
    }    
}

for inserting case comment you should follow the same logic to pass security review to honor CRUD\FLS

public void save_casecomment(){
    try{ 

        case_comment.parentid = [Select ID from Case where casenumber= :Case_ID].Id;

        if ( !Schema.sObjectType.CaseComment.isCreateable() ) {
            System.debug(LoggingLevel.Error, 'you don\'t have access to create CaseComment');
        } else if ( !Schema.sObjectType.CaseComment.fields.ParentId.isUpdateable() ) {
            System.debug(LoggingLevel.Error, 'you don\'t have access to update CaseComment ParentId');
        } else {
            insert case_comment; 
        }     
    }
    catch (Exception ex) {
        System.debug(LoggingLevel.Error, ' save_casecomment() Exception: ' + ex);
    }
    finally{
        case_comment_popup = false;
        case_comment = new CaseComment();
    }
} 
  • Even after using the above code, I Faceing the same Issue. Can you Please check my entire code an let me know were I'm wrong – Chandu Feb 12 '16 at 12:02
  • I have updated my answer – Patlatus Feb 12 '16 at 12:12
  • but thing is I'm Creating the new Case, Linking/connecting to that Contact, If we are Creating new Case we need to use 'isCreateable()' method right. – Chandu Feb 12 '16 at 12:19
  • yes, the user has access to create new case only if case.isCreateable() returns true – Patlatus Feb 12 '16 at 13:16
  • @Parlatus, thanks it working fine now and can you please explain how we write test cases for the same above code. – Chandu Feb 16 '16 at 6:31
1

Schema methods provide you the best way to perform CRUD and FLS Check. For example:

FLS Check

//Check if a field can be updated by current user
Schema.sObjectType.Account.fields.Name.isUpdateable()

CRUD Check

//Check if a record of this object can be updated
Account.sObjectType.getDescribe().isUpdateable()

Similarly you have:

isAccessible()
isCreateable()
isDeletable()
isQueryable()
isSearchable()

Complete list here

  • Crud/FLS is working fine, Please help me how to do code coverage for the same above code – Chandu Feb 16 '16 at 6:41
  • create a User with System Admin profile, and call the method in test class within the block, 'System.runAs(newlyCreatedUser)' – San Tosh Feb 16 '16 at 7:02
  • Please can provide me an example/Sample code. – Chandu Feb 16 '16 at 7:04
  • 1
    Profile objProfile = [Select Id, Name from Profile where Name =: 'System Administrator' limit 1]; User objeUser = [Select Id, ProfileId from User where Id=: UserInfo.getUserId()]; // Compare the logged in user has System Administrator profile if(objUser.ProfileId == objProfile.Id){ // Execute code } System.runAs(objUser){ //call the methods } – San Tosh Feb 16 '16 at 7:11
0

This is a bit late for answer. Someone else might find it useful  try this class to check fls by just passing query 

https://github.com/sonicfurqan/CheckCURDSalesforce.git

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.