0

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

Yaqub Ahmad
  • 27,569
  • 23
  • 102
  • 149
  • Code of your Retrieve plugin? How did you register your plugin? – Henk van Boeijen Sep 21 '15 at 11:11
  • 1
    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 Sep 21 '15 at 12:02
  • For which step(s) did you register your plugin? Can you share the Stack Trace? – Henk van Boeijen Sep 21 '15 at 12:05
  • @Alex Hmm. I am thinking about using the Access Teams.. – Yaqub Ahmad Sep 21 '15 at 12:38
  • @HenkvanBoeijen I have registered it for "Retrieve Post Operation", see the image in question. – Yaqub Ahmad Sep 21 '15 at 12:40
  • You should really think about using Team Ownership (not access teams, just two regular teams) or (if it is really only two categories) you could look at using two business units, Category 1 and Category 2, to get the necessary record level security. A plugin for this is overkill. – Nicknow Sep 22 '15 at 01:02

1 Answers1

1

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.

Henk van Boeijen
  • 7,357
  • 6
  • 32
  • 42
  • 1
    I have tried InvalidPluginExecutionException too.. We have decided to use Access Team for this functionality. – Yaqub Ahmad Sep 21 '15 at 14:34