Tip #1207: Check applied entity permissions in portals

Liquid is a great templating language adding flexibility to your Dynamics 365 Portal templates. However, as any abstraction, it hides some of the things happening under the hood, including some security filtering. Consider this fragment running on authenticated page:

{% fetchxml my_contacts %}
<fetch mapping="logical" version="1.0" 
       returntotalrecordcount="true">
  <entity name="contact">
    <attribute name="firstname"></attribute>
    <attribute name="lastname"></attribute>
    <attribute name="contactid"></attribute>
    <order descending="false" attribute="lastname">
    </order>
  </entity>
</fetch>
{% endfetchxml %}

<h2>Record count: 
  {{ my_contacts.results.total_record_count }}
</h2>

And… the count is 2 while expected to be the total number of contacts in this sample environment (around 20 or so) . Er?

This is because the portal engine applies entity permissions to all constructs retrieving the data including fetchxml. To see where did the things go wrong (or right – depending whether it’s your point of view or of your system administrator), use xml property of the fetchxml object. That will tell you what’s actually being executed.

<div style="white-space: pre-wrap;">
  <code>
    {{ my_contacts.xml | escape }}
  </code>
</div>

In my case resulting fetchxml looks like this

<fetch mapping="logical" version="1.0" 
  distinct="true" returntotalrecordcount="true">
  <entity name="contact">
    <attribute name="firstname" />
    <attribute name="lastname" />
    <attribute name="contactid" />
    <order attribute="lastname" descending="false" />
    <filter type="and">
      <filter type="or" hint="union">
        <condition attribute="parentcustomerid" 
        operator="eq" 
        value="deadbeef-38c9-e711-a844-000d3ad1181d" />
        <condition attribute="contactid" 
        operator="eq" 
        value="deadbeef-38c9-e711-a844-000d3ad1181d" />
      </filter>
    </filter>
  </entity>
</fetch>

highlighted lines (injected by the portal engine) explain why I’m seeing only two records (my portal is based on Customer Service):

  • deadbeef-38c9-e711-a844-000d3ad1181d is my contact id (after I logged in)
  • condition on contactid is a result of the “self” OOB Customer Service – Contact of the User entity permission that gives portal users permissions to access their own profile
  • condition on parentcustomerid is a result of the OOB Customer Service – Contact of the Contact entity permission giving portal users access to the contacts where they are the parent customer

Leave a Reply

Your email address will not be published. Required fields are marked *