Working with Field Level Security from a Plugin
Saturday, May 12, 2012 at 11:20PM Question: I was wondering if a plugin could update a field that is protected by Field Level Security (FLS), or if that is blocked in the platform
Answer: It Depends
If the plugin is running pre-operation stage and is modifying the entity image that is input parameters before the platform operation occurs then it doesn’t matter if the user that caused the operation to occur has permission to update the secured field the plugin will still be able to modify the value. It also doesn’t matter the context in which the plugin was registered to run in the plugin registration tool. The following is simple example of modifying new_secretcode that is enabled for field level security. This code was run from a plugin registered on create of account in the pre-operation stage.
var context = serviceProvider.GetService(typeof(IPluginExecutionContext)) as IPluginExecutionContext;
var target = context.InputParameters["Target"] as Entity;
target["new_secretcode"] = "1234";
To dive a little bit deeper let’s explore what happens when a plugin runs in post operation stage and attempts to create a record and populate the value of a secured field. For this example, I’ve modified the plugin to create a new account anytime a contact is created. As part of that it gets an organization service that runs in the context of the user that caused the platform operation to run. When run by the administration user the plugin fires and creates the account without any problem. When the contact was created by a user that did not have access to update secret code you would see the following error:
Here’s the revised code that is running when a contact is created and attempts to create the account and update the secured field:
var context = serviceProvider.GetService(typeof(IPluginExecutionContext)) as IPluginExecutionContext;
var target = new Entity("account");
target["name"] = "test 3";
target["new_secretcode"] = "1234";
var sf = serviceProvider.GetService(typeof(IOrganizationServiceFactory)) as IOrganizationServiceFactory;
var service = sf.CreateOrganizationService(Guid.Empty);
service.Create(target);
The key line to pay attention to above is the CreateOrganizationService call that we pass Guid.Empty. Passing Guid.Empty instructs the method to give back an organization service configured to run in the context of the user. If instead we passed null to that method the organization service would be configured to run in the system context and the plugin would be able to update the secured field.

Reader Comments