blog image

blog image

Monday, April 4, 2016

Crm Service Impersonation: Shared Views Management


  Here is a note about an interesting project involving crm service impersonation. Client had an idea to allow users subscribe to the only views they need and unsubscribe from extra views freely.

   Only view owner can share its views. The main issue here to give to user ability to share somebody’s views as the view owner without extending his security privileges.

  The project had a number of custom controls and entities. Here I’m going to describe only the security workaround by using a service impersonation.

Here is a “how to”, a very good example of service impersonation:

   The plugin can be registered on “Calling User”. The minimum permission your customers will need is “Read Access” to “UserQuery” entity. All OOB roles have it. 

First step: Get view owner.

 Given you have a User Query id. I'm getting it from one of custom entities.
//get query owner
Entity userQuery = service.Retrieve("userquery", userQueryId, new ColumnSet(new string[] { "ownerid" })); 

EntityReference owner = userQuery.GetAttributeValue<EntityReference>("ownerid");

!Don’t forget to check if owner is a user but not a team. 

Step two: Use service impersonation to manage the view as its owner 


!Use  context.UserId” as “userid” parameter to add/remove access.

-          unsubscribe

        public static void unsubscibe(IServiceProvider serviceProvider, Guid userid, ITracingService tracingService, Entity userQuery, EntityReference owner)

        { 

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            IOrganizationService serviceImpersonated = serviceFactory.CreateOrganizationService(owner.Id); 

EntityReference user = new EntityReference("systemuser", userid);

ModifyAccessRequest modifyUserAccessReq = new ModifyAccessRequest

            {
                PrincipalAccess = new PrincipalAccess
                {
                    AccessMask = AccessRights.None,
                    Principal = user
                },

                Target = userQuery.ToEntityReference(),
            };

ModifyAccessResponse responce = (ModifyAccessResponse)serviceImpersonated.Execute(modifyUserAccessReq);           

}
 

-          subscribe

        public static void subscibe(IServiceProvider serviceProvider, Guid userid, ITracingService tracingService, Entity userQuery, EntityReference owner)
        {
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            IOrganizationService serviceImpersonated = serviceFactory.CreateOrganizationService(owner.Id);

            EntityReference user = new EntityReference("systemuser", userid); 
           
            ModifyAccessRequest modifyUserAccessReq = new ModifyAccessRequest
            {
                PrincipalAccess = new PrincipalAccess
                {
                    AccessMask = AccessRights.ReadAccess,
                    Principal = user
                },

                Target = userQuery.ToEntityReference(),
            };

            ModifyAccessResponse responce = (ModifyAccessResponse)serviceImpersonated.Execute(modifyUserAccessReq);         

        }

Works elf, god bless impersonation :)

 

No comments: