Sample: Share records using GrantAccess, ModifyAccess and RevokeAccess messages
Applies To: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online
This sample code is for Microsoft Dynamics 365 (online & on-premises). Download the Microsoft Dynamics CRM SDK package. It can be found in the following location in the download package:
SampleCode\CS\GeneralProgramming\EarlyBound\UserAccess.cs
Requirements
For more information about the requirements for running the sample code provided in this SDK, see Use the sample and helper code.
Demonstrates
This sample shows how to share a record using the following messages:
Example
using System;
using System.Collections.Generic;
using System.ServiceModel;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
namespace Microsoft.Crm.Sdk.Samples
{
public class UserAccess
{
#region Class Level Members
private OrganizationServiceProxy _serviceProxy;
private Guid _currentUserId;
private List<Guid> _systemUserIds;
private Guid _teamId;
private Guid _leadId;
private Guid _taskId;
#endregion
#region How To Sample Code
public void Run(ServerConnection.Configuration serverConfig,
bool promptforDelete)
{
using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri,serverConfig.Credentials, serverConfig.DeviceCredentials))
{
// This statement is required to enable early bound type support.
_serviceProxy.EnableProxyTypes();
CreateRequiredRecords();
// Retrieve and display the access that the calling user has to the
// created lead.
var leadReference = new EntityReference(Lead.EntityLogicalName, _leadId);
var currentUserReference = new EntityReference(
SystemUser.EntityLogicalName, _currentUserId);
RetrieveAndDisplayPrincipalAccess(leadReference, currentUserReference,
"Current User");
// Retrieve and display the access that the first user has to the
// created lead.
var systemUser1Ref = new EntityReference(SystemUser.EntityLogicalName,
_systemUserIds[0]);
RetrieveAndDisplayPrincipalAccess(leadReference, systemUser1Ref,
"System User 1");
// Grant the first user read access to the created lead.
var grantAccessRequest1 = new GrantAccessRequest
{
PrincipalAccess = new PrincipalAccess
{
AccessMask = AccessRights.ReadAccess,
Principal = systemUser1Ref
},
Target = leadReference
};
Console.WriteLine("Granting {0} to {1} ({2}) on the lead...\r\n",
AccessRights.ReadAccess, GetEntityReferenceString(systemUser1Ref), "System User 1");
_serviceProxy.Execute(grantAccessRequest1);
// Retrieve and display access information for the lead.
RetrieveAndDisplayPrincipalAccess(leadReference, systemUser1Ref,
"System User 1");
RetrieveAndDisplayLeadAccess(leadReference);
// Grant the team read/write access to the lead.
var teamReference = new EntityReference(Team.EntityLogicalName, _teamId);
var grantAccessRequest = new GrantAccessRequest
{
PrincipalAccess = new PrincipalAccess
{
AccessMask = AccessRights.ReadAccess | AccessRights.WriteAccess,
Principal = teamReference
},
Target = leadReference
};
Console.WriteLine("Granting {0} to {1} ({2}) on the lead...\r\n",
AccessRights.ReadAccess | AccessRights.WriteAccess, GetEntityReferenceString(teamReference), "Team");
_serviceProxy.Execute(grantAccessRequest);
var systemUser2Ref = new EntityReference(SystemUser.EntityLogicalName,
_systemUserIds[1]);
// Retrieve and display access information for the lead and system user 2.
RetrieveAndDisplayPrincipalAccess(leadReference, systemUser2Ref,
"System User 2");
RetrieveAndDisplayLeadAccess(leadReference);
// Grant the first user delete access to the lead.
var modifyUser1AccessReq = new ModifyAccessRequest
{
PrincipalAccess = new PrincipalAccess
{
AccessMask = AccessRights.DeleteAccess,
Principal = systemUser1Ref
},
Target = leadReference
};
Console.WriteLine("Granting delete access to {0} on the lead...\r\n",
GetEntityReferenceString(systemUser1Ref));
_serviceProxy.Execute(modifyUser1AccessReq);
// Retrieve and display access information for the lead.
RetrieveAndDisplayLeadAccess(leadReference);
// Revoke access to the lead for the second user.
var revokeUser2AccessReq = new RevokeAccessRequest
{
Revokee = systemUser2Ref,
Target = leadReference
};
Console.WriteLine("Revoking access to the lead for {0}...\r\n",
GetEntityReferenceString(systemUser2Ref));
_serviceProxy.Execute(revokeUser2AccessReq);
// Retrieve and display access information for the lead.
RetrieveAndDisplayPrincipalAccess(leadReference, systemUser2Ref,
"System User 2");
RetrieveAndDisplayLeadAccess(leadReference);
DeleteRequiredRecords(promptforDelete);
}
}
private void RetrieveAndDisplayPrincipalAccess(EntityReference leadReference,
EntityReference principal, String additionalIdentifier)
{
var principalAccessReq = new RetrievePrincipalAccessRequest
{
Principal = principal,
Target = leadReference
};
var principalAccessRes = (RetrievePrincipalAccessResponse)
_serviceProxy.Execute(principalAccessReq);
Console.WriteLine("Access rights of {0} ({1}) on the lead: {2}\r\n",
GetEntityReferenceString(principal),
additionalIdentifier,
principalAccessRes.AccessRights);
}
private void RetrieveAndDisplayLeadAccess(EntityReference leadReference)
{
var accessRequest = new RetrieveSharedPrincipalsAndAccessRequest
{
Target = leadReference
};
// The RetrieveSharedPrincipalsAndAccessResponse returns an entity reference
// that has a LogicalName of "user" when returning access information for a
// "team."
var accessResponse = (RetrieveSharedPrincipalsAndAccessResponse)
_serviceProxy.Execute(accessRequest);
Console.WriteLine("The following have the specified granted access to the lead.");
foreach (var principalAccess in accessResponse.PrincipalAccesses)
{
Console.WriteLine("\t{0}:\r\n\t\t{1}",
GetEntityReferenceString(principalAccess.Principal),
principalAccess.AccessMask);
}
Console.WriteLine();
}
private String GetEntityReferenceString(EntityReference entityReference)
{
return String.Format("{0} with GUID {1}", entityReference.LogicalName,
entityReference.Id);
}
/// <summary>
/// Creates any entity records that this sample requires.
/// </summary>
public void CreateRequiredRecords()
{
// Create a unique identifier for this sample for preventing name conflicts.
var sampleIdentifier = Guid.NewGuid();
// Retrieve/create the system users to use for the sample.
var ldapPath = String.Empty;
_systemUserIds = SystemUserProvider.RetrieveDelegates(
_serviceProxy, ref ldapPath);
// Retrieve the root business unit to use for creating the team for the
// sample.
var businessUnitQuery = new QueryExpression
{
EntityName = BusinessUnit.EntityLogicalName,
ColumnSet = new ColumnSet("businessunitid"),
Criteria = new FilterExpression()
};
businessUnitQuery.Criteria.AddCondition("parentbusinessunitid",
ConditionOperator.Null);
var businessUnitResult = _serviceProxy.RetrieveMultiple(businessUnitQuery);
var businessUnit = businessUnitResult.Entities[0].ToEntity<BusinessUnit>();
// Get the GUID of the current user.
var who = new WhoAmIRequest();
var whoResponse = (WhoAmIResponse)_serviceProxy.Execute(who);
_currentUserId = whoResponse.UserId;
// Create a team for use in the sample.
var team = new Team
{
AdministratorId = new EntityReference(
"systemuser", _currentUserId),
Name = String.Format("User Access Sample Team {0}", sampleIdentifier),
BusinessUnitId = businessUnit.ToEntityReference()
};
_teamId = _serviceProxy.Create(team);
// Add the second user to the newly created team.
var addToTeamRequest = new AddMembersTeamRequest
{
TeamId = _teamId,
MemberIds = new[] { _systemUserIds[1] }
};
_serviceProxy.Execute(addToTeamRequest);
// Create a lead for use in the sample.
var lead = new Lead
{
CompanyName = "User Access Sample Company",
FirstName = "Sample",
LastName = "Lead",
Subject = "User Access Sample Lead",
};
_leadId = _serviceProxy.Create(lead);
// Create a task to associate to the lead.
var leadReference = new EntityReference(Lead.EntityLogicalName, _leadId);
var task = new Task
{
Subject = "User Access Sample Task",
RegardingObjectId = leadReference
};
_taskId = _serviceProxy.Create(task);
// Create a letter to associate to the lead.
var letter = new Letter
{
Subject = "User Access Sample Letter",
RegardingObjectId = leadReference
};
_serviceProxy.Create(letter);
}
private void DeleteRequiredRecords(bool prompt)
{
bool toBeDeleted = true;
if (prompt)
{
// Ask the user if the created entities should be deleted.
Console.Write("\nDo you want these entity records deleted? (y/n) [y]: ");
String answer = Console.ReadLine();
if (answer.StartsWith("y") ||
answer.StartsWith("Y") ||
answer == String.Empty)
{
toBeDeleted = true;
}
else
{
toBeDeleted = false;
}
}
if (toBeDeleted)
{
// Delete records created in this sample.
_serviceProxy.Delete(Team.EntityLogicalName, _teamId);
// Deleting the lead will delete its associated activities.
_serviceProxy.Delete(Lead.EntityLogicalName, _leadId);
Console.WriteLine("Entity record(s) have been deleted.");
}
}
#endregion How To Sample Code
#region Main method
/// <summary>
/// Standard Main() method used by most SDK samples.
/// </summary>
/// <param name="args"></param>
static public void Main(string[] args)
{
try
{
// Obtain the target organization's web address and client logon
// credentials from the user.
ServerConnection serverConnect = new ServerConnection();
ServerConnection.Configuration config = serverConnect.GetServerConfiguration();
var app = new UserAccess();
app.Run(config, true);
}
catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine("Timestamp: {0}", ex.Detail.Timestamp);
Console.WriteLine("Code: {0}", ex.Detail.ErrorCode);
Console.WriteLine("Message: {0}", ex.Detail.Message);
Console.WriteLine("Plugin Trace: {0}", ex.Detail.TraceText);
Console.WriteLine("Inner Fault: {0}",
null == ex.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault");
}
catch (System.TimeoutException ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine("Message: {0}", ex.Message);
Console.WriteLine("Stack Trace: {0}", ex.StackTrace);
Console.WriteLine("Inner Fault: {0}",
null == ex.InnerException.Message ? "No Inner Fault" : ex.InnerException.Message);
}
catch (System.Exception ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine(ex.Message);
// Display the details of the inner exception.
if (ex.InnerException != null)
{
Console.WriteLine(ex.InnerException.Message);
FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException
as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;
if (fe != null)
{
Console.WriteLine("Timestamp: {0}", fe.Detail.Timestamp);
Console.WriteLine("Code: {0}", fe.Detail.ErrorCode);
Console.WriteLine("Message: {0}", fe.Detail.Message);
Console.WriteLine("Plugin Trace: {0}", fe.Detail.TraceText);
Console.WriteLine("Inner Fault: {0}",
null == fe.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault");
}
}
}
// Additional exceptions to catch: SecurityTokenValidationException, ExpiredSecurityTokenException,
// SecurityAccessDeniedException, MessageSecurityException, and SecurityNegotiationException.
finally
{
Console.WriteLine("Press <Enter> to exit.");
Console.ReadLine();
}
}
#endregion Main method
}
}
See Also
GrantAccessRequest
User and team entities
Share
Sample: Create an on-premises user
Introduction to entities in Microsoft Dynamics 365
Microsoft Dynamics 365
© 2016 Microsoft. All rights reserved. Copyright