CRM 2013 Programmatically Comparing User Privileges

When debugging security issues it can be useful to compare the privileges of a functioning user with a non-functioning user.

The code in this post will print out all the privilege differences between two given users.

Differences between user1@gap.com and user2@gap.com
user1@gap.com has BU:root, PRIV:prvCreateAccount, DEPTH:Global
user1@gap.com has BU:root, PRIV:prvCreateActivity, DEPTH:Global
user1@gap.com has BU:root, PRIV:prvCreateArticle, DEPTH:Global

user2@gap.com has BU:sub, PRIV:prvCreateActivity, DEPTH:Deep
user2@gap.com has BU:sub, PRIV:prvCreateArticle, DEPTH:Global

class Program
{
	static Dictionary<Guid, String> privilegeNames;
	static Dictionary<Guid, String> businessUnits;

	enum Depth
	{
		User = 1,
		Bu = 2,
		Parent = 4,
		Global = 8
	};

	static StreamWriter file;               

	static void Main(string[] args)
	{
		IOrganizationService service = new OrganizationService(new CrmConnection("Connection"));

		privilegeNames = GetPrivilegeNames(service);
		businessUnits = GetBusinessUnits(service);

		Console.WriteLine("Enter domain name of first user...");
		String userA = Console.ReadLine();

		Console.WriteLine("Enter domain name of second user...");
		String userB = Console.ReadLine();
		
		using (file = new StreamWriter(@"C:\temp\User Comparision.txt"))
		{
			CompareUsers(service, userA, userB);
		}

		Console.Read();
	}

	static void CompareUsers(IOrganizationService service, String userA, String userB)
	{
		List<String> a = GetPrivileges(service, userA);

		List<String> b = GetPrivileges(service, userB);

		WriteLine(String.Format("Differences between {0} and {1}", userA, userB));
		bool differences = false;

		foreach (var t in a.Except(b))
		{
			differences = true;
			WriteLine(String.Format("{0} has {1}", userA, t));
		}

		foreach (var t in b.Except(a))
		{
			differences = true;
			WriteLine(String.Format("{0} has {1}", userB, t));
		}

		if (!differences)
		{
			WriteLine(String.Format("No differences between {0} and {1}", userA, userB));
		}
	}

	static List<String> GetPrivileges(IOrganizationService service, String userName)
	{
		Guid userId = GetUserId(service, userName);

		RetrieveUserPrivilegesRequest q = new RetrieveUserPrivilegesRequest();
		q.UserId = userId;

		RetrieveUserPrivilegesResponse r = (RetrieveUserPrivilegesResponse)service.Execute(q);

		return r.RolePrivileges.OrderBy(rp => privilegeNames[rp.PrivilegeId])
			.Select(rp => String.Format("BU:{0}, PRIV:{1}, DEPTH:{2}", businessUnits[rp.BusinessUnitId], privilegeNames[rp.PrivilegeId], rp.Depth))
			.ToList();
	}

	static Guid GetUserId(IOrganizationService service, String userName)
	{
		QueryExpression q = new QueryExpression("systemuser");
		q.Criteria.AddCondition("domainname", ConditionOperator.Equal, userName);

		return service.RetrieveMultiple(q).Entities.First().Id;
	}

	static Dictionary<Guid, String> GetBusinessUnits(IOrganizationService service)
	{
		QueryExpression q = new QueryExpression("businessunit");
		q.ColumnSet.AddColumn("name");
		return service.RetrieveMultiple(q).Entities.ToDictionary(e => e.Id, e => (String)e["name"]);
	}

	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 void WriteLine(String message)
	{
		file.WriteLine(message);
		Console.WriteLine(message);
	}
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s