Hide Views based on User Roles in Dynamics CRM

Welcome to my old Blogspot blog! You can read this post on our new website: Read this post on our new website 

There are many scenarios where one can need to hide views for user roles. Here is an example code to hide views on Account entity for specific roles.

Let us suppose that we need to hide "Inactive Accounts" and "Customers" views for Roles "Accounts Manager" & "CSR Manager".






























Here you need to write and register a plugin and add a plugin step as pre-operation on Message "RetrieveMultiple" of "savedquery" entity  as highlighted below:

Plugin code to hide specific views for specific roles:






















public void Execute(IServiceProvider sp)
{
   IPluginExecutionContext context = (IPluginExecutionContext)sp.GetService(typeof(IPluginExecutionContext));
   IOrganizationServiceFactory factory = (IOrganizationServiceFactory)sp.GetService(typeof(IOrganizationServiceFactory));
   IOrganizationService service = factory.CreateOrganizationService(context.UserId);     
   QueryExpression query = null;
    if (context.InputParameters.Contains("Query") && context.InputParameters["Query"] is QueryExpression)
            query = (QueryExpression)context.InputParameters["Query"];           
   if (query == null) return;
   if (query.EntityName != "savedquery") return;
   int entityTypeCode = 1;//Account
   string[] Roles = { "Account Manager", "CSR Manager" };
   string[] Views = { "Inactive Accounts", "Customers" };
   try
   {
      if (query.Criteria != null && query.Criteria.Conditions != null)
       {
          var rtcCondition = query.Criteria.Conditions.SingleOrDefault(c => c.AttributeName.Equals("returnedtypecode"));
          if (rtcCondition == null) return;
        
          int returnedtypecode = (int)rtcCondition.Values[0];          
          //Return if entity code is other than Account
          if (returnedtypecode != entityTypeCode) return;
          List<Role> LoginUserRoles = getUserRoles(context.InitiatingUserId, service);
          List<Role> desiredRoles = LoginUserRoles.Where(r => Roles.Contains(r.Name)).ToList();                 
          if(LoginUserRoles.Where(r => Roles.Contains(r.Name)).ToList().Count > 0)
           {
              ConditionExpression queryCondition = new ConditionExpression("name", ConditionOperator.NotIn, Views); 
              query.Criteria.Conditions.Add(queryCondition);
            } 
         }
     }
     catch (Exception ex)
     {
        throw new InvalidPluginExecutionException(ex.Message);
     }       
}
       
/// <summary>       
/// Get Login user roles    
/// </summary>    
/// <param name="userId">Login User (Initiating User)</param>  
/// <param name="service">IOrganizationService service</param>  
/// <returns></returns> 
private List<Role> getUserRoles(Guid userId, IOrganizationService service)
{
    Role role = null;
    List<Role> roles = null;
    var query = string.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
                                <entity name='role'>                                 
                                    <attribute name='name' /> 
                                    <attribute name='roleid' /> 
                                    <link-entity name='systemuserroles' from='roleid' to='roleid' visible='false' intersect='true'>
                                    <link-entity name='systemuser' from='systemuserid' to='systemuserid' alias='ab'>
                                    <filter type='and'>
                                    <condition attribute='systemuserid' operator='eq' value='{0}' />
                                    </filter>
                                   </link-entity> 
                                  </link-entity>
                                 </entity>
                                </fetch>", userId.ToString());
     EntityCollection result = service.RetrieveMultiple(new FetchExpression(query));
     if (result != null && result.Entities.Count > 0)
      {
          roles = new List<Role>();
          foreach (Entity e in result.Entities)
          {
                    role = new Role();
                    role.RoleID = e.Id;
                    if (e.Contains("name") && e["name"] != null)
                        role.Name = e["name"].ToString();
                    roles.Add(role);
            }
       }
       return roles;
}
       
public class Role 
{
   public Guid RoleID { get; set; }
   public string Name { get; set; }
}

After registering the plugin, the "Inactive Accounts" and "Customers" views are no more visible for users having role in "Accounts Manager" and "CSR Manager".





























Thanks-

3 comments:

  1. Very interesting plug-in. I didn't know System Views can be hidden like that. Thank you for sharing.

    ReplyDelete
  2. Thank you, Muhammad Siddique, for sharing this insightful blog.
    I'm curious whether it also applies to custom entities. I attempted to use a similar plugin for custom entities, but it didn't seem to function.
    Do you happen to know if it's designed solely for OOB entities or if it's compatible with custom ones as well?

    ReplyDelete
  3. it should work for custom entities as well. Feel free to share more details about the problems you're encountering, and I can help troubleshoot further.

    ReplyDelete