Hide Views based on User Roles in Dynamics CRM

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-

1 comment:

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

    ReplyDelete