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 :)
Comments