apex-enterprise-patterns / fflib-apex-common

Common Apex Library supporting Apex Enterprise Patterns and much more!
BSD 3-Clause "New" or "Revised" License
913 stars 517 forks source link

Can't run subSelect with enforceFLS & enforceCRUD = false as the Parent query does #235

Closed Emineminero closed 1 year ago

Emineminero commented 5 years ago

Hi, nowadays when trying to perform a subSelect I get an error that the user running it doesnt have permissions on the related Object. This is only happening for the object on the subSelect, since I'm setting newQueryFactory(false, false, true) for the parent query and that object isnt having problems.

The following example is being executed on a Without Sharing class: On this example we are querying for Accounts and their Contacts

fflib_QueryFactory accontQF = newQueryFactory(false, false, true)
                    .selectFields(new List<String>{
                            'Id',
                            'Name'
                    });

fflib_QueryFactory contactQF = new ContactsSelector().addQueryFactorySubselect(accontQF);
            contactQF.selectFields(new List<String>{'Id','Name'});
            return Database.query(
                    contactQF.toSOQL()
            );

This will throw an error saying that Permission to access a Contact denied

The query is being run on a Salesforce Site context, by a Site user where the profile doesnt have read access to Contact object. But thats why I'm running this on a Without Sharing class and I'm not enforcing FLS & CRUD.

ThomasPortierModis commented 3 years ago

Hi, I've encountered the same issue on different objects. I believe I was able to find a workaround which is described below :

public List<Account> selectWithContacts() {
    fflib_QueryFactory accountQueryFactory = newQueryFactory(false, false, true);
    accountQueryFactory.selectFields(new List<String>{ 'Id', 'Name' });

    ContactsSelector ctcSelector = new ContactsSelector();
    ctcSelector.ignoreCRUD();
    ctcSelector.addQueryFactorySubselect(accountQueryFactory, 'Contacts')
        .selectFields(new List<String>{ 'Id', 'Name' });

    return Database.query(accountQueryFactory.toSOQL());
}

In my case, It appears that an explicit instance of the childSelector (ContactsSelector) allows the use of the .ignoreCRUD() method, which seems to prevent the error when the Guest runs the code.

Hope it helps

daveespo commented 1 year ago

With the introduction of #419 the legacy enforceCRUD and enforceFLS flags are deprecated. Please consider switching to User Mode per the notes in that discussion.