0
votes

We want to implement 'Record level security' in MS CRM Dynamics. On User and Case Entity we have an OptionSet which has below values, that Optionset has a lot of values, below are just simple values:

  • Category 1
  • Category 2

We want to restrict Category 1 users to see only Category 1 Cases and to restrict Category 2 users to see only Category 2 Cases.

What I have done so far?

I was thinking that this should be possible through Retrieve plugin, but after I wrote my code.. I found that the retrieve plugin is triggering 5 times when I tried to open a case record. It also does not throw my custom error.

    public void Execute(IServiceProvider serviceProvider)
    {
        ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
        IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = factory.CreateOrganizationService(context.UserId);

        tracer.Trace("context.Depth = " + context.Depth);

        if (context.Depth > 1)
            return;

        tracer.Trace("context.Stage = " + context.Stage);

        tracer.Trace("context.MessageName = " + context.MessageName);


        EntityReference entityReference = (EntityReference)context.InputParameters["Target"];

        tracer.Trace("entityReferencee = " + entityReference.LogicalName);

        if (context.OutputParameters != null && context.OutputParameters.Contains("BusinessEntity"))
        {
            if (context.OutputParameters["BusinessEntity"] is Entity)
            {
                Entity entity = (Entity)context.OutputParameters["BusinessEntity"];

                tracer.Trace("entity.LogicalName = " + entity.LogicalName);

                context.OutputParameters["BusinessEntity"] = null;

                throw new Exception("You can not view this record.");

            }
            else
            {
                tracer.Trace("BusinessEntity entity is not an entity.");
            }
        }
        else
        {
            tracer.Trace("BusinessEntity entity is null");
        }
    }

This is how the plugin is registered: enter image description here

Error: enter image description here

Detail of Log File is given below:

Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Web.HttpUnhandledException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #CF526D62Detail:
-2147220970 System.Web.HttpUnhandledException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #CF526D62
2015-09-21T12:33:00.6154994Z -2147220956 Unexpected exception from plug-in (Execute): RestrictUserAccess.Case: System.Exception: You can not view this record. 2015-09-21T12:33:00.6154994Z

[RestrictUserAccess: RestrictUserAccess.Case] [c8860cb6-4260-e511-80ea-3863bb3600d8: RestrictUserAccess.Case: Retrieve of incident]

context.Depth = 1 context.Stage = 40 context.MessageName = Retrieve entityReferencee = incident entity.LogicalName = incident

1
Code of your Retrieve plugin? How did you register your plugin?Henk van Boeijen
What does the log file (Download log file) say ? Also, on a side note, this is what access teams are (supposedly) meant for, have you considered that approach ?Alex
For which step(s) did you register your plugin? Can you share the Stack Trace?Henk van Boeijen
@Alex Hmm. I am thinking about using the Access Teams..Yaqub Ahmad
@HenkvanBoeijen I have registered it for "Retrieve Post Operation", see the image in question.Yaqub Ahmad

1 Answers

1
votes

Your code does throw the exception, but the CRM platform handles it as an unexpected error. (Just read the log details.)

When you need to signal a functional error, you have to throw an InvalidPluginExecutionException.

It is possible that the system itself is retrieving the same Case record multiple times. Also scripting on your web form or in the ribbon can be responsible for retrieving the same record, e.g. when it needs to evaluate the record state.

Therefore throwing exceptions on retrieval of Case records may not be a useful solution. An alternative approach could be to clear all (or all sensitive) fields on retrieval by removing them from the Entity.Attributes collection.