Running Custom Code in Dynamics CRM Portal – Part 2 – Security

In a previous post, I talked about my experience running custom code from the portal. This method allowed a web file to be created and then called asynchronously from JavaScript. This post can be found at the link below, if you have not read it, I recommend reading it to provide context for the remainder of this post.

Running Custom Code in Dynamics CRM Portal

One of the major aspects missing from the last post is security. When the RetrieveMultiple plugin is triggered, it runs in the context of the system user. And, as it is written, the plugin does not have any knowledge of what portal user it was triggered by. This problem can be solved using the steps below.

Providing the current portal user (contact) id to the plugin

The first step is to pass the id of the current portal user to the plugin. This can be achieved by adding a condition to the FetchXml filter like below, along with adding a field to the Portal Actions entity.

Verifying Security on Organization Service Calls

The next step is to ensure that all calls to the OrganizationService have filtering applied. To do this, I created a class implementing the IOrganizationService interface which delegates calls to the organization service provided by the plugin. Then, when a call is made, I query the user’s entity permissions assigned through the associated web roles and then use these to determine what the user should be able to do and/or see.

Keep in mind that the Authenticated User web role is applied to Contacts automatically and will not always be explicitly assigned to the user.

Efficient Plugin Development

The process used when developing plugins can have a major influence on efficiency. This post explains the process that I have found to work best for me.

Planning

The first step of the development process is to determine whether the plugin should be placed in an existing assembly or in a new assembly. Having multiple assemblies allows multiple developers to work in parallel, however, it also increases the code’s footprint.

It is also beneficial to consider how files are organized within the plugin. I have found it works well to organize plugins by the entities that they are registered on. It can also be helpful to leave the namespace as the assembly namespace (although ReSharper will complain). This allows the files to be easily reorganized without being in the completely wrong namespace when compared to the folder structure.

Also, when creating the plugin, inheriting from a base class can be helpful. This minimizes boilerplate code, making the plugin easier to understand and more standardized.

Debugging

Exceptions and Plugin Profiler

When developers first start writing Dynamics plugins, they often insert Exceptions purely for use during the development process. They may write a trace after every line. Or, they may even use the Plugin Profiler. Although these can all be useful at times, they are not usually very efficient.

I have found the methods below have improved my development process.

Unit Testing

To allow unit testing, I move the bulk of the plugin functionality into a separate function. Then, I make this function public so that it can be called from a unit test. When calling this function, it is often simplest to identify a record in CRM to test against and then pass in this record id along with an Organization Service connected to the development organization. However, if the plugin needs to support many varied and/or complex cases then I will instead use FakeXrmEasy to ensure that the various cases are sufficiently tested.

Plugin Trace Log

If an issue is difficult to setup, or an issue is only occurring when the plugin has been deployed to CRM, then it can be helpful to debug using trace statements. To do this, enable the plugin logging built into recent versions of CRM, and then view the Plugin Trace Log through the XrmToolbox Plugin Trace Viewer. This eliminates the need to install the plugin profiler solution and allows tracing without adding extra Exceptions to the plugin.

Plugin Deployment

One more helpful tool in this process is the XrmToolbox Plugin Auto Deployer. This monitors the plugin assembly for changes and automatically updates the plugin in CRM when it is built within Visual Studio. When the plugin deployment tool is set to monitor the release build, the debug build can be used to work out most issues using unit testing without deploying to CRM. This also helps avoid interfering with other developers during development.

 

Let me know what works well for you in the comments below.

Quickly Updating Multiple Entity Attributes

Have you ever needed to make changes to a large number of fields? Perhaps 25 fields need their max value updated? All of the currency base fields need prefixed with zzz so they’re at the end of advanced find? You could go through and tediously open and change all of the fields. Or, you could use the Xrm Toolbox Bulk Attribute Editor.

This tool turns this process into 3 simple steps:

  1. Backup the entity being edited by creating and/or exporting a solution.
  2. Download and/or open “Attribute Editor” in XRM Toolbox.
  3. Click “Load Entities”.
  4. Select the entity to be edited from the entity drop-down.
  5. Click “Download Template”.
  6. Open the downloaded template.
  7. Edit the spreadsheet as necessary. Note that the logical name, schema name, and type columns should not be changed.
  8. Save and close the spreadsheet.
  9. Upload the edited template by clicking on the “…” to the left of the “Upload Template” button, selecting the spreadsheet, and then clicking “Upload Template”.
  10. Verify that the fields displayed in the grid match the expected fields.
  11. Click “Save Entity”.

Be sure to report any issues and/or suggestions in the comments below or at the Project Site:
https://github.com/bcolpaert/Colso.Xrm.AttributeEditor

Common Data Service

This post is intended to provide a high-level description of the Common Data Service. It took me some effort to come up with what I feel is a good summarized description, but, I eventually settled on this:

The Common Data Service is a scalable and standardized data store for integrating between and with Dynamics 365 applications.

Some of the advantages of the Common Data Service are below.

Standardized entities/fields between applications (Common Data Model)

The common data model provides a standardized set of entities/fields. The schema for these entities is automatically added when a database is created, and they cannot be deleted. Custom entities/fields can also be added as necessary. However, it is best to use the standardized entities/fields when possible. Using the standard model ensures that new features or apps can be leveraged by your application. Standardizing the model also allows developers that are familiar with the Common Data Service structure to quickly become familiar with other applications that utilize the same structure.

Consolidated data

Bringing data together in a single database helps to eliminate data silos between applications. It also allows data to be reported on from a central location. My initial thought was that the Common Data Service could potentially be used as a data warehouse. However, with the current limit of 10GB per database, I do not think this is a good fit nor is it Microsoft’s intention for the service.

Data Integration Service

This service provides a standard set of maps for integrating data with the Common Data Service. Two examples of these are Dynamics 365 for Sales and Dynamics AX. This is a core component of the Prospect to cash solution.