Sunday 29 May 2016

Compare Security role in Dynamic CRM Programatically

Many time during project while in development phase, unit testing , SIT testing or during support we get the requirement to compare security role with in same org or different org.
below console application will help to find out difference , similarity and download all roles.

   #region Class Level Members

        private static IOrganizationService _orgService;
        static System.IO.StreamWriter file;
        static Dictionary<String, Guid> roleIds;
        static Dictionary<Guid, String> privilegeNames;
        public static int userInput = 0;
        enum Depth
        {
            User = 1,
            Bu = 2,
            Parent = 4,
            OrgLevel = 8
        };

        #endregion Class Level Members
        public static void Main(string[] args)
        {

            Console.WriteLine("Enter values :");
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine("Enter : 1 for Difference in First not Second ");
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Enter : 2 for Difference in Second not First ");
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("Enter : 3 for Finding Similarity between two ");
            Console.ForegroundColor = ConsoleColor.Green;
             userInput = int.Parse(Console.ReadLine());
            String connectionString =  "Url=https://cts084.crm8.dynamics.com/; Username=username; Password=password; authtype=Office365";
            //    bool promptforDelete;

            CrmServiceClient conn = new Microsoft.Xrm.Tooling.Connector.CrmServiceClient(connectionString);
            _orgService = (IOrganizationService)conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient : (IOrganizationService)conn.OrganizationServiceProxy;
         

            roleIds = GetRoleIds(_orgService);

            privilegeNames = GetPrivilegeNames(_orgService);

            using (file = new StreamWriter(@"E:\SDK\Roles Comparison.txt"))
            {
                foreach (var pair in roleIds)
                {
                    var key = pair.Key;
                    CompareRoles(_orgService, "Marketing Manager", key.ToString());
                }
            }


        }

        static void CompareRoles(IOrganizationService service, String roleA, String roleB)
        {
            List<Tuple<String, Depth>> a = GetRolePrivileges(service, roleIds[roleA], privilegeNames);

            List<Tuple<String, Depth>> b = GetRolePrivileges(service, roleIds[roleB], privilegeNames);

     
            bool differences = false;
            bool similarity = false;

            //   bool similar = true;


            //  similarity = a.Equals(b);
            switch (userInput)
            {
                case 3:
                    {
                        if (similarity == false)
                        {
                            file.WriteLine(String.Format("Similarity between {0} and {1}", roleA, roleB));
                            foreach (var t in a)
                            {
                                similarity = false;
                                foreach (var g in b)
                                {
                                    similarity = (t.Item1.Equals(g.Item1) && t.Item2.Equals(g.Item2));
                                    if (similarity == true)
                                        file.WriteLine(String.Format("{0} has {1}: {2} similar to Role {3}", roleA, t.Item1, t.Item2, roleB));
                                }
                            }
                        }
                        break;
                    }

                case 1:
                    {
                        file.WriteLine(String.Format("Differences between {0} and {1}", roleA, roleB));

                        foreach (var t in a.Except(b))
                        {
                            differences = true;
                            file.WriteLine(String.Format("{0} has {1}: {2}", roleA, t.Item1, t.Item2));
                        }
                        break;
                    }
                case 2:
                    {
                        file.WriteLine(String.Format("Differences between {1} and {0}", roleB, roleA));
                        foreach (var t in b.Except(a))
                        {
                            differences = true;
                            file.WriteLine(String.Format("{0} has {1}: {2}", roleB, t.Item1, t.Item2));
                        }
                        break;
                    }
                default:
                    {
                        if (!differences)
                        {
                            file.WriteLine(String.Format("No differences between {0} and {1}", roleA, roleB));
                        }
                        break;
                    }
            }
            }

        static List<Tuple<String, Depth>> GetRolePrivileges(IOrganizationService service, Guid role, Dictionary<Guid, String> privilegeNames)
        {
            string fetch = @"<fetch version=""1.0"" output-format=""xml-platform"" mapping=""logical"">
                            <entity name=""roleprivileges"">
                                <attribute name=""privilegeid""/>
                                <attribute name=""privilegedepthmask""/>
                                <filter type=""and"">
                                    <condition attribute=""roleid"" operator=""eq"" value=""{0}""/>
                                </filter>
                            </entity>
                        </fetch>";

            fetch = fetch.Replace("{0}", role.ToString());

            return service.RetrieveMultiple(new FetchExpression(fetch)).Entities
                .Select(e => new Tuple<String, Depth>(privilegeNames[(Guid)e["privilegeid"]], (Depth)((int)e["privilegedepthmask"])))
                .OrderBy(p => p.Item1)
                .ToList();
        }

        static Dictionary<Guid, String> GetPrivilegeNames(IOrganizationService service)
        {
            QueryExpression q = new QueryExpression("privilege");
            q.ColumnSet = new ColumnSet("name");

            return service.RetrieveMultiple(q).Entities.ToDictionary(e => e.Id, e => (String)e["name"]);
        }

        static Dictionary<String, Guid> GetRoleIds(IOrganizationService service)
        {


            QueryExpression q = new QueryExpression("role")
            {
                ColumnSet = new ColumnSet("name"),
                Criteria =
            {
                Conditions =
                {
                    new ConditionExpression("businessunitid", ConditionOperator.EqualBusinessId)
                }
            }
            };

            return service.RetrieveMultiple(q).Entities.ToDictionary(e => (String)e["name"], e => e.Id);
        }

    }

Saturday 21 May 2016

Odata in MSCRM 2016

Odata is now in a for of Web API MSCRM 2016
exmaple of ODATA
https://URL/accounts?$select=name&$expand=primarycontactid($select=contactid%20,fullname)%20&$filter=primarycontactid/contactid%20eq%20contactId
List accounts starting with A and C
var qry = “accounts?$filter=startswith(name,’A’) or startswith(name,’C’)”;

List accounts owned by a particular user
var qry = “accounts?$select=name,accountnumber,_primarycontactid_value,createdon,accountcategorycode,revenue&$filter=_ownerid_value
Read account details along with the primary contact phone.
We need to use the $expand clause to request data of related entity. However it appears that the $expand clause only works when requesting data of a single record as shown in the below query.

List all Phone Calls of an account
This will display only the subject of the related phone calls.




1function WhoAmIRequest() {
2var clientUrl = Xrm.Page.context.getClientUrl();
3var req = new XMLHttpRequest()
4req.open("GET", encodeURI(clientUrl + "/api/data/v8.0/WhoAmI()"), true);
5req.setRequestHeader("Accept", "application/json");
6req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
7req.setRequestHeader("OData-MaxVersion", "4.0");
8req.setRequestHeader("OData-Version", "4.0");
9req.onreadystatechange = function () {
10if (this.readyState == 4 /* complete */) {
11req.onreadystatechange = null;
12if (this.status == 200) {
13var data = JSON.parse(this.response);
14alert("User Id : "+data.UserId+"\nBusiness Unit Id : "+data.BusinessUnitId+ "\nOrganization Id : "+data.OrganizationId);
15}
16else {
17 
18var error = JSON.parse(this.response).error;
19alert(error.message);
20}
21}
22 
23};
24req.send();
25}