2

I recently run into a problem when I try to check fls within an without sharing class.

Here is what I did:

For the user profile I set CustomObject__c allow delete permission to "False"

public without sharing class TestSharing {

    public static String TestAccess() {
        CustomObject__c c = new CustomObject__c();
        c.CustomField__c = 'abc';
        insert c;

        Schema.DescribeSObjectResult d = c.getSObjectType().getDescribe();

        System.assertEquals(d.isDeletable(),true);
        return null;
    }
}

I am wondering what should d.isDeletable() return if I am running TestSharing.TestAccess()?

I was expecting it to return true (ignoring profile settings), because TestSharing is a without sharing class. However, it seems the value is always false disregarding the class sharing type.

2 Answers 2

6

All security-related methods, such as UserRecordAccess and the describe calls, will always return the user's real permissions. All that "without sharing" does is turns off the permission and sharing table checks when querying, updating, or deleting records. It is strongly recommended by salesforce.com that developers check for a user's permission to fields, objects, and records being used when using "without sharing," but there are times when this behavior is desirable, such as logging data to an object the user doesn't have direct access to.

2
  • Yes, this seems as the best way to explain the result I am getting. Could you point me to any salesforce documentation about this? Commented Mar 6, 2017 at 18:30
  • @bluecatkaka I can't seem to find any documentation on this, but I'm pretty sure I've read it somewhere before. If I do find it, I'll update this answer.
    – sfdcfox
    Commented Mar 6, 2017 at 19:22
6

without sharing will not reinforce SFDC field level access and visibility, so you will be running your class on system context.

In system context, Apex code has access to all objects and fields— object permissions, field-level security, sharing rules aren’t applied for the current user. This is to ensure that code won’t fail to run because of hidden fields or objects for a user. The only exceptions to this rule are Apex code that is executed with the executeAnonymous call and Chatter in Apex. executeAnonymous always executes using the full permissions of the current user. For more information on executeAnonymous

So you can see that making those changes will affect your access level to the fields and the visibility. The only exception in on executeAnonymous from you Developer Console and also triggers run on system context.

To find out your attributes for an object you can use the WorkBench Log in with the credentials for the org you are running that code. On the jump to: select : Standard & Custom Objects . Select the object, in this case, the CustomObject__c, you want to check and look under the attribute folder.

Also, your code needs to point to a specific object, like you do on this line CustomObject__c c = new CustomObject__c();. There you will find the Deletable() value.

Pretty sure that it is set to false if the assertEquals is returning false.

3
  • Do you mean in my specific case, the values from d.isDeletable() should return true? However, when I run this code as a user using the profile which as "deletable" turn off, the d.isDeletable() always give false value... Commented Mar 6, 2017 at 18:14
  • If you set up the Deletable() to true then you should get a positive response from your: System.assertEquals(d.isDeletable(),true); You can use Workbench to check the values like Deletable() for any object: Commented Mar 6, 2017 at 18:17
  • I have set Deletable() to false. Since without sharing is running the class on system context so it should will not reinforce sfdc object access, which will make d.isDeletable() always return true no matter what I set for "Deletable()", is that correct? Commented Mar 6, 2017 at 18:26

You must log in to answer this question.

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