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);
        }

    }