Allowing any User to Edit Custom Settings

Custom settings are an awesome tool for the Force.com developer. They allow you to control code, formulas, workflow rules and more on the platform. The problem is that they are a little hard to update since they don’t come with a tab, page layouts or other features of a full fledged object.

In order to manage a custom setting through the interface Salesforce provides, you must grant the user “Customize Application” permission. Now, this permission shouldn’t be handed out to just anyone. It allows users to edit layouts, object, fields and more. In some cases, you may want to let your users edit a custom setting, but don’t want them to get the other power of Customize Application.

The solution to this is to create a Visualforce page that you can give access to your users. I merrily went down this route recently and it all worked well until I actually logged in as one of the users and got a nasty surprise when I went to save the record. An error appeared on the page:  “system.security.NoAccessException: Update access denied for SuperDuperSetting__c”. I tried all sorts of things including trying to set my controller to use “without sharing”, call a webservice method, and JavaScript Remoting. The only thing that worked was JavaScript Remoting, but it was a bit messy and I wasn’t happy with it.

I then started examining my debug logs and realized my save code wasn’t even executing. The error was happening somewhere upstream of the save method. This got me thinking about Visualforce and object binding. Sure enough, the problem was because I had bound my VF page directly to an instance of the custom setting. The VF page was allowing my user to view the setting, but when I did any method, including a cancel, it blocked it. It wasn’t letting me get to my code. I created a proxy class that mirrored my custom object and bound my VF page to it instead. Lo and behold my limited user was now able to save the custom setting.

Here’s my VF page which works with both controllers. Followed by the code that only works if the user has Customize Application permissions and then the code that works for everyone.