330 words
2 minutes
Implementing Role-Based Access Control using RetrieveMultiple Plugin

Implementing Role-Based Access Control using RetrieveMultiple Plugin#

Project Setup#

  1. Launch Visual Studio and create a new Class Library project for your plugin
  2. Add references to the necessary Dynamics 365 assemblies:
    • Microsoft.Crm.Sdk.Proxy
    • Microsoft.Xrm.Sdk

RetrieveMultiple Plugin Code Implementation#

This plugin restricts access to records in the Account entity based on the “Dealer” field value.

using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System.ServiceModel;
using System.Linq;

namespace RetrieveMultiplePlugin
{
    public class RestrictAccountRecords : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            // Check if the request is a RetrieveMultiple request for the Account entity
            if (context.MessageName.Equals("RetrieveMultiple") && 
                context.InputParameters.Contains("Query") && 
                context.PrimaryEntityName == "account")
            {
                EntityCollection resultCollection = new EntityCollection();
                EntityCollection inputCollection = (EntityCollection)context.OutputParameters["BusinessEntityCollection"];
                
                if (inputCollection != null && inputCollection.Entities.Count > 0)
                {
                    foreach (Entity account in inputCollection.Entities)
                    {
                        // Check if the current user has the Dealer role
                        bool userIsDealer = CheckUserIsDealer(context.UserId, service);

                        if (userIsDealer)
                        {
                            // Check the value of the "Dealer" field
                            if (account.Contains("new_dealerfield") && (bool)account["new_dealerfield"])
                            {
                                resultCollection.Entities.Add(account);
                            }
                        }
                        else
                        {
                            // Allow access for non-Dealers
                            resultCollection.Entities.Add(account);
                        }
                    }

                    // Replace the original result with the filtered collection
                    context.OutputParameters["BusinessEntityCollection"] = resultCollection;
                }
            }
        }

        private bool CheckUserIsDealer(Guid userId, IOrganizationService service)
        {
            QueryExpression query = new QueryExpression("systemuser");
            query.ColumnSet = new ColumnSet("systemuserid");
            query.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId);

            EntityCollection userEntities = service.RetrieveMultiple(query);
            Entity user = userEntities.Entities.FirstOrDefault();

            if (user != null)
            {
                // Check if the user has the Dealer role
                if (user.Contains("new_isdealer") && (bool)user["new_isdealer"])
                {
                    return true;
                }
            }

            return false;
        }
    }
}

Registration and Deployment#

  1. Build the plugin project
  2. Sign the assembly if required
  3. Register the plugin assembly in your Dynamics 365 environment using:
    • Plugin Registration Tool
    • Package Deployer
    • Other registration methods
  4. Configure the step for:
    • Message: RetrieveMultiple
    • Entity: Account
  5. Deploy and test your plugin

Testing Procedure#

  1. Dealer User Test:

    • Log in as a user with the “Dealer” role
    • Retrieve Account records
    • Should only see records where “Dealer” field = true
  2. Non-Dealer User Test:

    • Log in as a regular user
    • Retrieve Account records
    • Should see all Account records

Customization Notes#

  • Adjust the field names (new_dealerfield, new_isdealer) to match your schema
  • Modify role checking logic as per your security requirements
  • Consider adding error handling for production environments
Implementing Role-Based Access Control using RetrieveMultiple Plugin
https://crmte.ch/posts/retrievemulti/
Author
Anu Prakash
Published at
2023-10-18
License
CC BY-NC-SA 4.0