Controlling Activate and Deactivate Permissions using Roles in Dynamics CRM 2011

Out of the box, Microsoft Dynamics CRM 2011 does not have the ability to control the permissions related to activating and deactivating records. However, with some minor customisation, you can deploy a solution to your instance that gives you this capability.

The following is an example of a very basic solution that leverages the power of the custom roles available in CRM. This example will allow for users to have a specific role assigned to them which will then grant them the permission to activate or deactivate a record for all entities.

Firstly, you need to create a new role in the CRM. This can be done by navigating to the Administration screen under the Settings section and selecting the Security Roles option:
Security Role Configuration

Create a new role and take note of the name. We called our role ‘Record Activation and Deactivation‘. This role is designed to work in conjunction with other roles as we are not specifying any permissions directly on to this role.

Next, we need to create a plugin. This plugin will retrieve any roles associated with the current user as we have specified in the condition expression. You can specify any number of roles that you wish to check for. In this example, we are checking for the ‘Record Activation and Deactivation‘ role and the ‘System Administrator‘ role.

If we have a match, we let the plugin complete without any further processing. If we don’t, we throw an IPluginException which will indicate to the user that they do not have the required roles to activate/deactivate this particular entity.

 public class EntitySetStatePlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            var service = serviceFactory.CreateOrganizationService(context.UserId);
            var tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            if (context.InputParameters.Contains("EntityMoniker") &&
                context.InputParameters["EntityMoniker"] is EntityReference)
            {
                var userId = context.UserId;
                var linkQuery = new QueryExpression()
                {
                    EntityName = "role",
                    Distinct = true,
                    ColumnSet = new ColumnSet("roleid"),
                    LinkEntities =
                    {
                        new LinkEntity()
                        {
                            LinkFromEntityName = "role",
                            LinkFromAttributeName = "roleid",
                            LinkToEntityName = "systemuserroles",
                            LinkToAttributeName = "roleid",
                            LinkEntities =
                            {
                                new LinkEntity()
                                {
                                    LinkFromEntityName = "systemuserroles",
                                    LinkFromAttributeName = "systemuserid",
                                    LinkToEntityName = "systemuser",
                                    LinkToAttributeName = "systemuserid",
                                    LinkCriteria =
                                    {
                                        Conditions =
                                        {
                                            new ConditionExpression("systemuserid", ConditionOperator.Equal, userId)
                                        }
                                    }
                                }
                            }
                        }
                    },
                    Criteria = new FilterExpression
                    {
                        Conditions =
                        {
                            new ConditionExpression("name", ConditionOperator.In,
                                new string[] {"Record Activation and Deactivation", "System Administrator"})
                        }
                    }
                };
                var haveRole = service.RetrieveMultiple(linkQuery).Entities.Count > 0;
                if (!haveRole)
                    throw new InvalidPluginExecutionException("You cannot modify the active/inactive state of this entity manually.");

We will register this plugin against the SetState and SetStateDynamicEntity messages.

pluginregisteractivate

Finally, assign the appropriate role to the users that require the ability to activate or deactivate records. Please note that these users will also need permissions to read the roles entity for the plugin to work correctly.

With that, we are now able to control the activate and deactivate functionality via a security role. The beauty with this approach is that you can choose to register this against only one particular entity or add some additional logic to the plugin so that it behaves differently based on which entity is being activated or deactivated.

For more information about Microsoft CRM, click here.