15

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

11

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;
        }

    }
}
| improve this answer | |
  • 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 '19 at 7:00
  • I don't know. I've never had to submit an app for security review. – Daniel Hoechst Feb 21 '19 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.

| improve this answer | |
  • Can a guest user make updates to Custom settings? – Mahesh Khandelwal Apr 28 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.

| improve this answer | |
  • 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 '14 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? – Daniel Ballinger Feb 20 '14 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

| improve this answer | |

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.