Friday, September 07, 2012

MS CRM 2011: How to check user rights on client side

Today I have got requirement to write function which will validate rights of user. In our specific case we had to show/hide buttons on custom web form. I decided to post results of my work here.
CheckUserPrivilege = function (privilegeName) {
    var context = (typeof GetGlobalContext != "undefined") ? GetGlobalContext() : Xrm.Page.context;

    var requestXml = "" +
    "  " +
    "    " +
    "      " +
    "        " +
    "          false" +
    "          " +
    "        " +
    "        " +
    "          " +
    "            " +
    "              name" +
    "              Equal" +
    "              " +
    "                " + privilegeName + "" +
    "              " +
    "            " +
    "          " +
    "          And" +
    "          " +
    "          false" +
    "        " +
    "        false" +
    "        privilege" +
    "        " +
    "          " +
    "            " +
    "              false" +
    "              " +
    "            " +
    "            " +
    "            Inner" +
    "            " +
    "              " +
    "              And" +
    "              " +
    "              false" +
    "            " +
    "            " +
    "              " +
    "                " +
    "                  false" +
    "                  " +
    "                " +
    "                " +
    "                Inner" +
    "                " +
    "                  " +
    "                  And" +
    "                  " +
    "                  false" +
    "                " +
    "                " +
    "                  " +
    "                    " +
    "                      false" +
    "                      " +
    "                    " +
    "                    " +
    "                    Inner" +
    "                    " +
    "                      " +
    "                        " +
    "                          systemuserid" +
    "                          EqualUserId" +
    "                          " +
    "                        " +
    "                      " +
    "                      And" +
    "                      " +
    "                      false" +
    "                    " +
    "                    " +
    "                    roleid" +
    "                    privilege" +
    "                    roleid" +
    "                    systemuserroles" +
    "                  " +
    "                " +
    "                roleid" +
    "                privilege" +
    "                parentrootroleid" +
    "                role" +
    "              " +
    "            " +
    "            privilegeid" +
    "            privilege" +
    "            privilegeid" +
    "            roleprivileges" +
    "          " +
    "        " +
    "        " +
    "        " +
    "          0" +
    "          0" +
    "          " +
    "          false" +
    "        " +
    "        false" +
    "      " +
    "    " +
    "  " +
    "";


    var xhr = new XMLHttpRequest();
    xhr.open("POST", context.prependOrgName("/XRMServices/2011/Organization.svc/web"), false)
    xhr.setRequestHeader("Accept", "application/xml, text/xml, */*");
    xhr.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    xhr.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/RetrieveMultiple");
    xhr.send(requestXml);

    if (xhr.responseXML.selectSingleNode('s:Envelope/s:Body/RetrieveMultipleResponse/RetrieveMultipleResult/a:Entities').childNodes.length != 0) {
        return true;
    }

    return false;
}


And here is sample of usage:

OnLoad = function () {
    if (CheckUserPrivilege("prvCreateIncident")) {
        alert("User has privileges to create icidents");
    }
    else {
        alert("User doesn't have privileges to create icidents");
    }
}

8 comments:

  1. Hi Andri,

    Does the request XML you created is a MSFT standard declaration to check for the user privileges ? and if I pass "prvCreateContact" to CheckuserPrivilege function would it be checking for my privilege without not modification to your code ?

    If that can be done then it's marvellous.

    Also, Just a simple request please correct "Incident" spell in your alert. Hope it's have gone to production now

    ReplyDelete
    Replies
    1. Sorry Andri, For my above request. due to asynchronous code highlighting I got completely different view of code. Just after highlight I got to know it's actually a SOAP XML. Thanks.

      Delete
    2. Hello,
      It seems that I've found bug in this highlighter.

      ' is shown as ".

      To fix it you will have to go trough Soap Request and fix namespaces. For example
      <a:columns xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      should look like
      <a:columns xmlns:b='http://schemas.microsoft.com/2003/10/Serialization/Arrays'>

      Delete
  2. Hi Andrii.
    first of all, thank you! I've been looking for this code for a long time!

    I'm trying to use your code, but I don't know why I'm receving an error "Bad Request" en the xhr status is 400.

    Any idea?
    WTW: The code that is in the post, isn't the same that the one in the popup window to copy it. The code from the popup has some xml directives.

    Thanks in advance.

    ReplyDelete
    Replies
    1. Hello Mictian,
      It seems that code highlighter doesn't work properly.
      Leave your email in comment and I will send you a source code.

      Delete
    2. Thank you Andrii, but fortunately I have made it work.
      But I have a problem when the users are in a different BU that the roles. In that case your query return false, when actually I have that privilege.

      Do you have any idea?

      Thanks in advance

      Delete
  3. This woould work great in crm 4 as well, but with the introduction of odata in mscrm 2011, the codes to check for user roles and privilege can be dramatically shrunk down.

    ReplyDelete
    Replies
    1. I tested this code exactly in CRM 2011 and it works without any issues.

      Delete