17

I'm working on a VF page to give some users access to certain custom settings without given them the entire Customize Application access.

Is there anyway to edit and commit data into the system as an admin during that instance ? IF not, is there a way to grant individual Custom setting access?

I've messed around with Delegated Administration on Custom Settings - the ironic thing about this feature is it grants users access to the custom settings' metadata (adding/deleting fields) but does not grant access to insert data.

Would love to get everyone's feedback! I'm not looking for access to the VF page, I'm looking for access to a specific custom setting itself.

Best, Eric

0

4 Answers 4

12

You can get around the need for a user to have the Customize Application permission if you proxy the custom setting object through another class or properties in your controller. If your VF page is bound directly to an instance of the custom setting, then you get messed up by the custom setting security. I think this is similar to how VF enforces field level security even when the Apex class does not. Here's a gist showing what does and doesn't work: https://gist.github.com/dhoechst/b437230ffd3d0bd6cd02.

My VF page:

<apex:page controller="SuperDuperSettingController">
    <apex:pageMessages />
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockSection >
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Name</apex:outputLabel>
                    <apex:inputText value="{!setting.Name}"/>                
                </apex:pageBlockSectionItem>
            </apex:pageBlockSection>
            <apex:pageBlockButtons >
                <apex:commandButton action="{!save}" value="Save" />
            </apex:pageBlockButtons>
        </apex:pageBlock>
    </apex:form>
</apex:page>

And my controller with a proxy class:

public class SuperDuperSettingController {

    public SettingProxy setting {get; set;}

    public SuperDuperSettingController() {
        String settingId = ApexPages.currentPage().getParameters().get( 'id' );
        if (settingId != null ) {
            setting = new SettingProxy([SELECT Id, Name FROM SuperDuperSetting__c WHERE Id = :settingId]);
        } else {
            setting = new SettingProxy();
        }
    }

    public PageReference save() {
        if (setting.Id != null) {
            update setting.getSuperDuperSetting();
        } else {
            setting.insertSetting();
        }
        PageReference pr = Page.SuperDuperSetting;
        pr.getParameters().put('Id', setting.Id);
        pr.setRedirect(true);
        return pr;
    }

    public class SettingProxy {
        public Id Id {get;set;}
        public String Name {get;set;}

        public SettingProxy(SuperDuperSetting__c sdp) {
            this.Id = sdp.Id;
            this.Name = sdp.Name;
        }

        public SettingProxy() {}

        public SuperDuperSetting__c getSuperDuperSetting() {
            return new SuperDuperSetting__c(
                Id = this.Id,
                Name = this.Name
            );
        }

        public void insertSetting() {
            SuperDuperSetting__c sdp = this.getSuperDuperSetting();
            insert sdp;
            this.Id = sdp.Id;
        }

    }
}
2
  • Hi Daniel, is this workable code for SF security review with false-positive document? I am letting users without customize application update there credentials in Salesforce. Credentials are stored inside protected custom setting.
    – Shankish
    Feb 21, 2019 at 7:00
  • I don't know. I've never had to submit an app for security review. Feb 21, 2019 at 19:50
3

Custom Settings have nothing to do with sharing. Making your classes without sharing might cause your classes to disregard other permissions, but not custom settings.

Custom settings have two permissions:

  • Everyone can always read a public custom setting (and apex code can). If the setting is a protected and it is within a managed package, then no one can read the setting (but Apex code running within the namespace can).

  • Only those with 'customize application' permission can modify a public custom setting. No one can modify a protected custom setting (but apex code running in the namespace can).

In other words, for custom settings, apex code within the same namespace will always be able to access them for both read and write. It doesn't matter if the code is with or without sharing, as sharing has nothing to do with custom settings.

However, custom settings have their own CRUD/FLS settings -- you can query each custom setting by its api name and get the result to an isUpdateable call, for example. And the results of these calls are respected in the default visualforce components that respect CRUD/FLS (e.g. inputField and outputField versus inputText and outputText). Therefore you cannot use these (*field) components in order to update custom settings unless the user has customize application permission.

Please don't try to fix known visualforce component behavior by introducing a bunch of without sharing classes in your controller. One is not a solution for the other, but rather by burying your field data within another class, you are forced to not use the visualforce *field components, and this is what makes it appear as if multiple 'without sharing' classes are the answer to your problem.

1
  • Can a guest user make updates to Custom settings? Apr 28, 2020 at 15:57
1

EDIT: As Eric points out in his comment, this doesn't work. Custom settings don't follow normal CRUD/FLS rules; they are governed by the "Customize Application" perm. Original answer follows.

Wrap up the logic to save settings into a class declared 'without sharing'. The code will execute in system context. Depending on the complexity of your VF Page, you could just write a custom controller and make that class 'without sharing'. You can then control access to the VF page by profile as normal.

2
  • 1
    Great idea Jason! I tried that route already as a global class without sharing. The user is able to VIEW the data but not CREATE/EDIT/DELETE.
    – Eric Luu
    Feb 19, 2014 at 22:50
  • I'm surprised I haven't run into this before. I use a custom VF page and controller to set username and password details into a protected custom setting. When the managed package is deployed to clients the VF page is the only way to insert/update the values. Maybe most people have this permission on by default? Feb 20, 2014 at 0:42
1

Have a read of Standard User can't add/edit custom setting record in salesforce which describes much the same problem and a couple of possible solutions:

  1. Rather than using a custom setting use a custom object instead. If these are user specific settings it might be easier. Unfortunately you giveup on the hierachy structure that custom settings give you.
  2. The asker of that question reportedly got it working by introducing an additional proxy class using without sharing. It isn't really clear why an extra class would be required if the controller is already using the same sharing setting.

See also:
Salesforce Ideas: Make 'Customize Application' permission more granular

You must log in to answer this question.

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