Monday, 13 January 2014

Get user's roles in MS Dynamics Crm 2011/2013

In MS Dynamics CRM 2011/13 there exists a JavaScript function to get the user's roles (Xrm.Page.context.getUserRoles) unfortunately, there are two problems with this function:
  1. It does not retrieve all roles, just those directly assigned to the user. In other words, if the user is a member of a team and that team has a role, this function will not find it.
  2. It returns the guids of the user roles rather than the names.

So in order to get around those shortcomings I wrote this function, which will return an array with all roles the user has including team roles. Note that this function is will only work in IE9+ as neither IE7 nor IE8 support indexOf, something that I will discuss in an upcoming post. It seems to work fine in Chrome (31) and Firefox (25).

function getAllUserRoles()
{
    var guid = "[A-z0-9]{8}-[A-z0-9]{4}-[A-z0-9]{4}-[A-z0-9]{4}-[A-z0-9]{12}";

    var serverUrl = Xrm.Page.context.getClientUrl();         
    var userId = Xrm.Page.context.getUserId();
    userId = userId.match(guid);
             
    var teamQuery = "TeamMembershipSet?$select=TeamId&$filter=SystemUserId eq guid'"+userId +"'";
    var teamRoleQuery = "TeamRolesSet?$select=RoleId&$filter=";
    var roleQuery = "RoleSet?$select=Name&$filter=";
    
    var teams = makeRequest(serverUrl,teamQuery,0);
    
    teamRoleQuery = composeQuery(teamRoleQuery,"TeamId",teams);
    var teamRoles = makeRequest(serverUrl,teamRoleQuery,1);

    userRoles = Xrm.Page.context.getUserRoles();
 
    if(userRoles != null){
     for(var i =0; i< userRoles.length;i++){
     teamRoles.push(userRoles[i].match(guid));
     }
    }

    roleQuery = composeQuery(roleQuery,"RoleId",teamRoles);
    var roles = makeRequest(serverUrl,roleQuery,2);
    
    return roles;
}

function makeRequest(serverUrl, query, type)
{

    var oDataEndpointUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc/";
    oDataEndpointUrl += query;

    var service = GetRequestObject();

    if (service != null)
    {

        service.open("GET", oDataEndpointUrl, false);
        service.setRequestHeader("X-Requested-With", "XMLHttpRequest");
        service.setRequestHeader("Accept", "application/json, text/javascript, */*");
        service.send(null);

        var retrieved = $.parseJSON(service.responseText).d;

        var results =  new Array();
                               
        switch (type)
        {

        case 0:
        for (var i=0; i < retrieved.results.length;i++){
          results.push(retrieved.results[i].TeamId);
          }
          break;
        case 1:
        for (var i=0; i < retrieved.results.length;i++){
          results.push(retrieved.results[i].RoleId);
          }
          break;

        case 2:
        for (var i=0; i < retrieved.results.length;i++){
          if(results.indexOf(retrieved.results[i].Name)==-1){
           results.push(retrieved.results[i].Name);
           }
          }
          break;
         }                                     
        return results;
     }
return null;
}

function GetRequestObject()
{

    if (window.XMLHttpRequest)
    {
        return new window.XMLHttpRequest;
    }
    else
    {
        try
        {
            return new ActiveXObject("MSXML2.XMLHTTP.3.0");
        }
        catch (ex)
        {
            return null;
        }
    }
}

function composeQuery (queryBase, attribute, items )
{
 if (items != null){
     for(var i=0; i < items.length; i++){
      if (i==0)
      {
       queryBase += attribute + " eq (guid'"+items[i]+"')";
      }
      else
      {
       queryBase += " or " + attribute + " eq (guid'"+items[i]+"')";
      }
     }
    }
 return queryBase;
}

 
I think one of these days I will get the hang of JavaScript but I still find it really obnoxious to work with.

No comments:

Post a Comment