Manage Profile Field Permissions with Apex

 



Recently, I encountered several cases where I needed to update profile permissions for fields in bulk. I was a bit disappointed to find that there are few free tools for such a task, and most of the ones I tested suffered from limitations of one kind or another. 

Because this is a recurring issue and also out of a desire to learn, I decided to try writing such a tool.

While exploring the options, I discovered that this can be done directly through Apex code. The permissions for the fields are stored in an object called FieldPermissions and users with setup permission can perform operations on the object.


The requirement was straightforward:

  • Option for selecting profiles and permissions.
  • Option for selecting a set of fields, including fields from different objects.
  • Checkboxes to modify the selected fields permissions for the profiles.
  • A save button, which will update the changes.


So I wrote a component (lwc) embedded in the Lightning Page that allows multiple selection of profiles or permission sets as well as multiple fields, editing and saving.

I would have liked to write that it is a simple process, but not this time. Managing permission is usually not an easy process.

Although it is about managing records in one object, there are special cases that require special attention. For example, you must not give write permission on a field formula, some standard fields that cannot receive permissions, and probably a few more that I haven't discovered yet.


I didn't publish the code for this process yet, as it is unstable, but I can share a few guidelines for anyone dealing with similar tasks:


  • Obviously, you cannot grant edit access to a field without also granting read access.
  • There are standard fields that cannot have permissions, for example, Id and CreatedBy. In most cases, we can identify those using the method isPermissionable from DescribeFieldResult
System.debug('Account.Rating isPermissionable: ' + Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap().get('Rating').getDescribe().isPermissionable());
System.debug('Account.Id isPermissionable: ' + Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap().get('Id').getDescribe().isPermissionable());

//01:44:58:103 USER_DEBUG [1]|DEBUG|Account.Rating isPermissionable: true
//01:44:58:123 USER_DEBUG [2]|DEBUG|Account.Id isPermissionable: false

  • There are other cases that the method isPermissionable doesn't cover; for example, you cannot provide permission for different sections of an Address field (e.g. BillingCity, BillingCountry), even though those fields are available in the object. Should give access only to the main field (BillingAddress).
  • Cannot provide edit access for formula fields.
  • Removing access for a field can be done either by deleting the FieldPermissions record or by setting Edit/Read both to false. In such a case, Salesforce will automatically delete it. It also means that when querying the existing permissions for fields with no access, you won't find a FieldPermissions record.
  • For my requirement, I added permissions only for fields, but a similar process can be done for object permissions and Apex/Pages permissions using the standard objects ObjectPermissions and SetupEntityAccess, respectively.
  • Cannot grant access for manage permission set (should be obvious)


Summary 

After dealing with such a process and understanding some of the difficulties involved, I can see why there are few such free quality tools. In my opinion, if you encounter such a need for mass update field permissions, the first recommendation is to try to use the existing tools. Either the Salesforce standard, even if sometimes it takes more time, or external tools.

Another option is to write a one-time script that will update/create relevant FieldPermissions records. 

List<FieldPermissions> newFieldsPermission = new List<FieldPermissions>();

newFieldsPermission.add(new FieldPermissions(
	PermissionsRead = true,
	PermissionsEdit = true,
	ParentId = 'ProfileOrPermssionSetId',
	SobjectType = 'Account',
	Field = 'Accunt.Rating')));

insert newFieldsPermission;


It is also possible to construct the relevant data in a csv and then import it to Salesforce as any other data. 






No comments:

Post a Comment

Retire of Permission on Profiles

If you are working as a Salesforce admin/developer you've probably heard somewhere that Salesforce is planning to make a significant cha...