MS-CRM Access finder from Fetch XML based API

Hello and Welcome!

Today you will have something which is not there on internet.

Access Finder through Fetch XML based API or SDK.

What i mean by access finder
> Access finder as in if someone wants to know on specific entity what access does user has and what all privileges and also from which security role.


So, Microsoft CRM provide one of the amazing feature called “security role”
One user can have multiple Security role and on each security role user can have different privilege level,
For E.G :
A user call Bob – is having following security role with privilege on “Account” entity

Now from above screenshots, we can tell that how hard it is to know a user having what level of access on which entity.

its even harder for Technical team, as while updating a record on user context, user may or may not have access to those entity and that could raise an error and snag for project.

We also faced similar issue some days back.

We had a requirement where a user calls CRM API from integrated website.
While creating record user was not able to make out what access he has on which entity and thus many time it raised bugs for technical team.

So i generated on FetchXML which can be used in SDK as well as ODATA API of CRM.

This API or fetch XML will return us the list of access that specific user has on specified entity.

Following is the Fetch XML

MS CRM Fetch XML

<fetch>
    <entity name="role" >
        <link-entity name="teamroles" from="roleid" to="roleid" visible="false" intersect="true">
            <link-entity name="team" from="teamid" to="teamid" alias="team">
                <attribute name="teamid" />
                <attribute name="name" />
                <link-entity name="teammembership" from="teamid" to="teamid" visible="false" intersect="true">
                    <link-entity name="systemuser" from="systemuserid" to="systemuserid" alias="ad">
                        <filter type="and">
                            <condition attribute="systemuserid" operator="eq" value="{CurrentUserID}" />
                        </filter>
                    </link-entity>
                </link-entity>
            </link-entity>
        </link-entity>
        <link-entity name="role" from="roleid" to="parentrootroleid" link-type="inner" alias="parentrootrole" >
            <attribute name="name" />
            <link-entity name="roleprivileges" from="roleid" to="roleid" link-type="inner" alias="privrole" intersect="true" >
                <attribute name="privilegedepthmask" />
                <link-entity name="privilege" from="privilegeid" to="privilegeid" link-type="inner" alias="priv" >
                    <attribute name="accessright" />
                    <attribute name="name" />
                   
                </link-entity>
                <link-entity name="privilegeobjecttypecodes" from="privilegeid" to="privilegeid" link-type="inner" alias="POTC" >
                    <attribute name="objecttypecode" />
                </link-entity>
            </link-entity>
        </link-entity>
    </entity>
</fetch>

Following is the API for above fetch XML which can be called as API from postman or any integrated system (Python, C#, Java)

https://[OrginsationName].crm11.dynamics.com/api/data/v9.0/roles?fetchXml=<fetch>
    <entity name="role" >
        <link-entity name="teamroles" from="roleid" to="roleid" visible="false" intersect="true">
            <link-entity name="team" from="teamid" to="teamid" alias="team">
                <attribute name="teamid" />
                <attribute name="name" />
                <link-entity name="teammembership" from="teamid" to="teamid" visible="false" intersect="true">
                    <link-entity name="systemuser" from="systemuserid" to="systemuserid" alias="ad">
                        <filter type="and">
                            <condition attribute="systemuserid" operator="eq" value="{CurrentUserID}" />
                        </filter>
                    </link-entity>
                </link-entity>
            </link-entity>
        </link-entity>
        <link-entity name="role" from="roleid" to="parentrootroleid" link-type="inner" alias="parentrootrole" >
            <attribute name="name" />
            <link-entity name="roleprivileges" from="roleid" to="roleid" link-type="inner" alias="privrole" intersect="true" >
                <attribute name="privilegedepthmask" />
                <link-entity name="privilege" from="privilegeid" to="privilegeid" link-type="inner" alias="priv" >
                    <attribute name="accessright" />
                    <attribute name="name" />
                   
                </link-entity>
                <link-entity name="privilegeobjecttypecodes" from="privilegeid" to="privilegeid" link-type="inner" alias="POTC" >
                    <attribute name="objecttypecode" />
                </link-entity>
            </link-entity>
        </link-entity>
    </entity>
</fetch>

Response from above API of fetch XML –

{
   "@odata.context":"https://[orgurl].crm11.dynamics.com/api/data/v9.0/$metadata#roles(roleid)",
   "value":[
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":4,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"46d8132c-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":8,
         "team.name":"Leads no owner ",
         "priv.name":"prvAppendAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":32,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"cd98cd38-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":1,
         "team.name":"Leads no owner (Web generated)",
         "priv.name":"prvCreateAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":32,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"bab00e1a-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":1,
         "team.name":"Leads no owner (imported)",
         "priv.name":"prvCreateAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":32,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"46d8132c-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":1,
         "team.name":"Leads no owner",
         "priv.name":"prvCreateAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":65536,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"cd98cd38-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":1,
         "team.name":"Leads no owner (Web generated)",
         "priv.name":"prvDeleteAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":65536,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"bab00e1a-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":1,
         "team.name":"Leads no owner (imported)",
         "priv.name":"prvDeleteAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":65536,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"46d8132c-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":1,
         "team.name":"Leads no owner ",
         "priv.name":"prvDeleteAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":524288,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"cd98cd38-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":1,
         "team.name":"Leads no owner (Web generated)",
         "priv.name":"prvAssignAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":524288,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"bab00e1a-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":1,
         "team.name":"Leads no owner (imported)",
         "priv.name":"prvAssignAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":524288,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"46d8132c-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":1,
         "team.name":"Leads no owner ",
         "priv.name":"prvAssignAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":262144,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"cd98cd38-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":8,
         "team.name":"Leads no owner (Web generated)",
         "priv.name":"prvShareAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":262144,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"bab00e1a-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":8,
         "team.name":"Leads no owner (imported)",
         "priv.name":"prvShareAccount"
      },
      {
         "@odata.etag":"W/\"8061497\"",
         "roleid":"59577672-f12f-4a20-aebf-f668931a2edc",
         "priv.accessright":262144,
         "parentrootrole.name":"Sales Professional Person",
         "team.teamid":"46d8132c-117e-ea11-a811-000d3a871931",
         "POTC.objecttypecode":"account",
         "privrole.privilegedepthmask":8,
         "team.name":"Leads no owner ",
         "priv.name":"prvShareAccount"
      }
   ]
}

You can add condition based on requirement,
Like, if you need to check if current user has access to share account or not,
just put filter by pvr.accessright = 262144

Real life scenario could be – When doing any transaction from integration layer to CRM, you may need to first identify if user has that specific privileges or not.

Hope it helps.
Feel free to connect for any queries or doubts.

Leave a comment