CRM Blog

Hide/Show fields in CRM 4.0 based on Security Role

by Zahara Hirani 05.08.08
There is a great blog by Ronald Lemmen regarding hiding and showing fields based on Security Roles for CRM 3.0 (http://ronaldlemmen.blogspot.com/2006/05/finally-there-show-and-hide-fields.html). Unfortunately, that code does not work for CRM 4.0 as the SystemUser web service is no longer available (or at least I couldn’t find it). So after much digging and fusing some of Ronald’s code, here is what I found.

In CRM 4.0, the “WhoAmI” method can be called using the CRM Service Execute method.
We first create an xmlhttp object and using the “Post” method specifies the request to be handled synchronously.
We then create the request object and using the xmlhttp send method retrieves the response.
The response can be accessed using xmlhttp.responseXML and can be loaded into an XML DOM object (xmlDoc).
The response xml returned contains the system user id and the business unit id associated to the system user.
Once we get the user id, we can use the UserManager web service and use the GetUserRoles method to retrieve all the security roles that exists in CRM.
All the roles that the system user is a part of will have a ‘checked=true’ value.
We then check if the current user has the role we are validating against and based on the result hide/show the certain fields.

Below is the code that would need to be placed in the entity’s OnLoad Event. In our case, I am trying to hide the section with the Estimated Revenue field on an opportunity for all CSR role users:

                  //Based on the role of the user logged in, hide the revenue tab on the opportunity
                  if(currentUserHasRole('Customer Service Representative'))
                  {
                        crmForm.all.estimatedrevenue.parentElement.parentElement.parentElement.style.display='none';
                  }
            }
            catch(e)
            
            {
                  
alert("There was an error with this field\'s customized event\u002e\n\nField\u003a crmForm\n\nEvent\u003a onload\n\nError\u003a " + e.description);
            }
      }
}

function getUserId()
{
      try
      {
            var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
            xmlhttp.open("POST", "../../mscrmservices/2007/crmservice.asmx", false);
            xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
            xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Execute");
            var soapBody = "<soap:Body>"+ "<Execute xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+ "<Request xsi:type='WhoAmIRequest' />"+ "</Execute></soap:Body>";
            var soapXml = "<soap:Envelope " + "xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' "+ "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "+ "xmlns:xsd='http://www.w3.org/2001/XMLSchema'>";
            soapXml += GenerateAuthenticationHeader();
            soapXml += soapBody;
            soapXml += "</soap:Envelope>";
            xmlhttp.send(soapXml);
            xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async=false;
            xmlDoc.loadXML(xmlhttp.responseXML.xml);
            var userid = xmlDoc.getElementsByTagName("UserId")[0].childNodes[0].nodeValue;
            return userid;
      }
      catch(e)
      {
            return null;
      }
}


function getUserRoles(userId)
{
      try
      {
            var command = new RemoteCommand("UserManager", "GetUserRoles");
            command.SetParameter("userIds", "<guid>" + userId + "</guid>");
            var oResult = command.Execute();
            if (oResult.Success)
            {
                  return oResult.ReturnValue;
            }
      }
      catch(e)
      {
      return null;
      }
}

function userHasRole(userId, roleName)
{
      var hasRole = false;
      result = getUserRoles(userId);
      if (result != null)
      {
            var oXml = new ActiveXObject("Microsoft.XMLDOM");
            oXml.resolveExternals = false;
            oXml.async = false;
            oXml.loadXML(result);
            roleNode = oXml.selectSingleNode("/roles/role[name='" + roleName + "']");
            if (roleNode != null)
            {
                  if (roleNode.selectSingleNode("roleid[@checked='true']") != null)
                  {
                        hasRole = true;
                  }
            }
      }
      return hasRole;
}

function currentUserHasRole(roleName)
{
      userId = getUserId();
      return userHasRole(userId, roleName);
}

function Test()
{
      if(true)
      {
            try
            {
Filed under:

Comments

# PM said on May 30, 2008 04:36 PM:

When I use this code I get the Microsoft general error. Am I supposed to leave some of this code out or replace something?

# PM said on May 30, 2008 05:44 PM:

I got it to work by

changing this:

"localhost/.../crmservice.asmx"

to this:

"/mscrmservices/2007/crmservice.asmx"

My problem now is trying to get the code to only run for a NEW form.

The code is this:

var MyForm = crmForm.FormType;

if (MyForm == 1)

{

}

But, I do not know where to place it within the code.

Any suggestions?

# Zahara Hirani said on June 1, 2008 01:46 PM:

PM,

Did you want the code to only trigger if its a new form? If so, you only want the code to validate on a Create Form Type.

Here is the start piece of your form OnLoad :

var MyForm = crmForm.FormType;

if (MyForm == 1)

{

  //Based on the role of the user logged in, hide the revenue tab on the opportunity

  if(currentUserHasRole('Customer Service Representative'))

  {

     crmForm.all.estimatedrevenue.parentElement.parentElement.parentElement.style.display='none';

  }

}

}

catch(e)            

{....

You can use the rest of the code from the catch.

Hope this help!

Zahara

Leave a Comment

(required) 
(required) 
(optional)
(required)