1652 lines
60 KiB
C#
1652 lines
60 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using System.Data.SqlClient;
|
||
using System.Globalization;
|
||
using System.IO;
|
||
using System.Net;
|
||
using System.Reflection;
|
||
using System.Net.Security;
|
||
using System.Security.Principal;
|
||
using System.Security.Cryptography.X509Certificates;
|
||
using System.Threading;
|
||
using System.ServiceModel.Description;
|
||
using Microsoft.Win32;
|
||
using WebsitePanel.Providers.Common;
|
||
using WebsitePanel.Providers.ResultObjects;
|
||
using WebsitePanel.Server.Utils;
|
||
using Microsoft.Xrm.Sdk;
|
||
using Microsoft.Xrm.Sdk.Query;
|
||
using Microsoft.Xrm.Sdk.Discovery;
|
||
using Microsoft.Xrm.Sdk.Client;
|
||
using Microsoft.Xrm.Sdk.Deployment;
|
||
using Microsoft.Xrm.Sdk.Messages;
|
||
|
||
|
||
namespace WebsitePanel.Providers.HostedSolution
|
||
{
|
||
public class CRMProvider2011 : HostingServiceProviderBase, ICRM
|
||
{
|
||
private static string crmPath = null;
|
||
|
||
#region Properties
|
||
|
||
private string UserName
|
||
{
|
||
get { return ProviderSettings[Constants.UserName]; }
|
||
}
|
||
|
||
private string Password
|
||
{
|
||
get { return ProviderSettings[Constants.Password]; }
|
||
}
|
||
|
||
private string SqlServer
|
||
{
|
||
get { return ProviderSettings[Constants.SqlServer]; }
|
||
}
|
||
|
||
private string ReportingServer
|
||
{
|
||
get { return ProviderSettings[Constants.ReportingServer]; }
|
||
}
|
||
|
||
private string CRMServiceUrl
|
||
{
|
||
get
|
||
{
|
||
string cRMServiceUrl = "https://" + ProviderSettings[Constants.AppRootDomain] + ":" + ProviderSettings[Constants.Port] + "/XRMDeployment/2011/Deployment.svc";
|
||
return cRMServiceUrl;
|
||
}
|
||
}
|
||
|
||
private string CRMDiscoveryUri
|
||
{
|
||
get
|
||
{
|
||
string cRMDiscoveryUri = "https://" + ProviderSettings[Constants.AppRootDomain] + ":" + ProviderSettings[Constants.Port] + "/XRMServices/2011/Discovery.svc";
|
||
return cRMDiscoveryUri;
|
||
}
|
||
}
|
||
|
||
private static string CrmPath
|
||
{
|
||
get
|
||
{
|
||
if (string.IsNullOrEmpty(crmPath))
|
||
{
|
||
RegistryKey root = Registry.LocalMachine;
|
||
RegistryKey rk = root.OpenSubKey("SOFTWARE\\Microsoft\\MSCRM");
|
||
if (rk != null)
|
||
{
|
||
crmPath = (string)rk.GetValue("CRM_Server_InstallDir", string.Empty);
|
||
}
|
||
}
|
||
return crmPath;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
#region Static constructor
|
||
|
||
static CRMProvider2011()
|
||
{
|
||
AppDomain.CurrentDomain.AssemblyResolve += ResolveCRMAssembly;
|
||
}
|
||
|
||
#endregion
|
||
|
||
static Assembly ResolveCRMAssembly(object sender, ResolveEventArgs args)
|
||
{
|
||
var loadedAssembly = default(Assembly);
|
||
// Ensure we load DLLs only.
|
||
if (args.Name.ToLower().Contains("microsoft.crm") || args.Name.ToLower().Contains("antixsslibrary"))
|
||
{
|
||
//
|
||
string crmToolsPath = Path.Combine(CrmPath, "tools");
|
||
//
|
||
string path = Path.Combine(crmToolsPath, args.Name.Split(',')[0] + ".dll");
|
||
// Call to load an assembly only if its existence is confirmed.
|
||
if (File.Exists(path))
|
||
{
|
||
loadedAssembly = Assembly.LoadFrom(path);
|
||
}
|
||
}
|
||
//
|
||
return loadedAssembly;
|
||
}
|
||
|
||
private bool CheckCRMWebServicesAccess()
|
||
{
|
||
Log.WriteStart("CheckCRMWebServicesAccess");
|
||
bool ret = false;
|
||
HttpWebResponse response = null;
|
||
HttpWebRequest request;
|
||
|
||
try
|
||
{
|
||
WindowsIdentity.GetCurrent();
|
||
|
||
request = WebRequest.Create(CRMServiceUrl) as HttpWebRequest;
|
||
|
||
if (request != null)
|
||
{
|
||
request.UseDefaultCredentials = true;
|
||
request.Credentials = CredentialCache.DefaultCredentials;
|
||
response = request.GetResponse() as HttpWebResponse;
|
||
|
||
}
|
||
if (response != null)
|
||
ret = (response.StatusCode == HttpStatusCode.OK);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.WriteError(ex);
|
||
ret = false;
|
||
}
|
||
|
||
Log.WriteEnd("CheckCRMWebServicesAccess");
|
||
return ret;
|
||
}
|
||
|
||
private static bool CheckPermissions()
|
||
{
|
||
Log.WriteStart("CheckPermissions");
|
||
bool res = false;
|
||
try
|
||
{
|
||
string group = "PrivUserGroup";
|
||
string user = WindowsIdentity.GetCurrent().Name.Split(new char[] { '\\' })[1];
|
||
res = ActiveDirectoryUtils.IsUserInGroup(user, group);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.WriteError(ex);
|
||
res = false;
|
||
}
|
||
|
||
Log.WriteEnd("CheckPermissions");
|
||
return res;
|
||
}
|
||
|
||
private bool CheckOrganizationUnique(string databaseName, string orgName)
|
||
{
|
||
Log.WriteStart("CheckOrganizationUnique");
|
||
bool res = false;
|
||
|
||
SqlConnection connection = null;
|
||
try
|
||
{
|
||
connection = new SqlConnection();
|
||
connection.ConnectionString =
|
||
string.Format("Server={1};Initial Catalog={0};Integrated Security=SSPI",
|
||
databaseName, SqlServer);
|
||
|
||
connection.Open();
|
||
|
||
string commandText = string.Format("SELECT COUNT(*) FROM dbo.Organization WHERE UniqueName = '{0}'", orgName);
|
||
SqlCommand command = new SqlCommand(commandText, connection);
|
||
int count = (int)command.ExecuteScalar();
|
||
res = count == 0;
|
||
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
res = false;
|
||
Log.WriteError(ex);
|
||
}
|
||
finally
|
||
{
|
||
if (connection != null)
|
||
connection.Dispose();
|
||
|
||
}
|
||
|
||
Log.WriteEnd("CheckOrganizationUnique");
|
||
return res;
|
||
}
|
||
|
||
private bool CheckSqlServerConnection()
|
||
{
|
||
Log.WriteStart("CheckSqlServerConnection");
|
||
bool res = false;
|
||
SqlConnection connection = null;
|
||
try
|
||
{
|
||
connection = new SqlConnection();
|
||
connection.ConnectionString =
|
||
string.Format("server={0}; Integrated Security=SSPI",
|
||
SqlServer);
|
||
|
||
connection.Open();
|
||
res = true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.WriteError(ex);
|
||
res = false;
|
||
}
|
||
finally
|
||
{
|
||
if (connection != null)
|
||
connection.Dispose();
|
||
}
|
||
|
||
Log.WriteEnd("CheckSqlServerConnection");
|
||
|
||
return res;
|
||
}
|
||
|
||
private bool CheckReportServerConnection()
|
||
{
|
||
Log.WriteStart("CheckReportServerConnection");
|
||
bool ret = false;
|
||
HttpWebResponse response = null;
|
||
HttpWebRequest request;
|
||
|
||
try
|
||
{
|
||
WindowsIdentity.GetCurrent();
|
||
|
||
request = WebRequest.Create(ReportingServer) as HttpWebRequest;
|
||
|
||
if (request != null)
|
||
{
|
||
request.UseDefaultCredentials = true;
|
||
request.Credentials = CredentialCache.DefaultCredentials;
|
||
response = request.GetResponse() as HttpWebResponse;
|
||
|
||
}
|
||
if (response != null)
|
||
ret = (response.StatusCode == HttpStatusCode.OK);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.WriteError(ex);
|
||
ret = false;
|
||
}
|
||
|
||
Log.WriteEnd("CheckReportServerConnection");
|
||
return ret;
|
||
}
|
||
|
||
private OrganizationResult CheckCrmEnvironment(string strDataBaseName, string organizationUniqueName)
|
||
{
|
||
OrganizationResult retOrganization = StartLog<OrganizationResult>("CheckCrmEnvironment");
|
||
bool res = CheckSqlServerConnection();
|
||
|
||
if (!res)
|
||
{
|
||
EndLog("CheckCrmEnvironment", retOrganization, CrmErrorCodes.CRM_SQL_SERVER_ERROR);
|
||
return retOrganization;
|
||
}
|
||
|
||
res = CheckOrganizationUnique(strDataBaseName, organizationUniqueName);
|
||
if (!res)
|
||
{
|
||
EndLog("CheckCrmEnvironment", retOrganization, CrmErrorCodes.CRM_ORGANIZATION_ALREADY_EXISTS);
|
||
return retOrganization;
|
||
}
|
||
|
||
res = CheckReportServerConnection();
|
||
if (!res)
|
||
{
|
||
EndLog("CheckCrmEnvironment", retOrganization, CrmErrorCodes.CRM_REPORT_SERVER_ERROR);
|
||
return retOrganization;
|
||
}
|
||
|
||
res = CheckPermissions();
|
||
if (!res)
|
||
{
|
||
EndLog("CheckCrmEnvironment", retOrganization, CrmErrorCodes.CRM_PERMISSIONS_ERROR);
|
||
return retOrganization;
|
||
}
|
||
|
||
res = CheckCRMWebServicesAccess();
|
||
if (!res)
|
||
{
|
||
EndLog("CheckCrmEnvironment", retOrganization, CrmErrorCodes.CRM_WEB_SERVICE_ERROR);
|
||
return retOrganization;
|
||
}
|
||
|
||
EndLog("CheckCrmEnvironment");
|
||
return retOrganization;
|
||
}
|
||
|
||
public OrganizationResult CreateOrganization(Guid organizationId, string organizationUniqueName, string organizationFriendlyName, string baseCurrencyCode, string baseCurrencyName, string baseCurrencySymbol, string initialUserDomainName, string initialUserFirstName, string initialUserLastName, string initialUserPrimaryEmail, string organizationCollation)
|
||
{
|
||
return CreateOrganizationInternal(organizationId, organizationUniqueName, organizationFriendlyName, baseCurrencyCode, baseCurrencyName, baseCurrencySymbol, initialUserDomainName, initialUserFirstName, initialUserLastName, initialUserPrimaryEmail, organizationCollation);
|
||
}
|
||
|
||
const string CRMSysAdminRoleStr = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;System Administrator";
|
||
|
||
internal OrganizationResult CreateOrganizationInternal(Guid organizationId, string organizationUniqueName, string organizationFriendlyName, string baseCurrencyCode, string baseCurrencyName, string baseCurrencySymbol, string initialUserDomainName, string initialUserFirstName, string initialUserLastName, string initialUserPrimaryEmail, string organizationCollation)
|
||
{
|
||
OrganizationResult ret = StartLog<OrganizationResult>("CreateOrganizationInternal");
|
||
|
||
if (organizationId == Guid.Empty)
|
||
throw new ArgumentException("OrganizationId is Guid.Empty");
|
||
|
||
if (string.IsNullOrEmpty(organizationFriendlyName))
|
||
throw new ArgumentNullException("organizationFriendlyName");
|
||
|
||
if (string.IsNullOrEmpty(baseCurrencyCode))
|
||
throw new ArgumentNullException("baseCurrencyCode");
|
||
|
||
if (string.IsNullOrEmpty(baseCurrencySymbol))
|
||
throw new ArgumentNullException("baseCurrencySymbol");
|
||
|
||
if (string.IsNullOrEmpty(initialUserDomainName))
|
||
throw new ArgumentNullException("initialUserDomainName");
|
||
|
||
string strDataBaseName = "MSCRM_CONFIG";
|
||
|
||
OrganizationResult retCheckEn = CheckCrmEnvironment(strDataBaseName, organizationUniqueName);
|
||
|
||
if (!retCheckEn.IsSuccess)
|
||
{
|
||
ret.ErrorCodes.AddRange(retCheckEn.ErrorCodes);
|
||
EndLog("CreateOrganizationInternal", ret, null, null);
|
||
return ret;
|
||
}
|
||
|
||
try
|
||
{
|
||
|
||
Uri serviceUrl = new Uri(CRMServiceUrl);
|
||
|
||
DeploymentServiceClient deploymentService = Microsoft.Xrm.Sdk.Deployment.Proxy.ProxyClientHelper.CreateClient(serviceUrl);
|
||
|
||
Microsoft.Xrm.Sdk.Deployment.Organization org = new Microsoft.Xrm.Sdk.Deployment.Organization
|
||
{
|
||
Id = organizationId,
|
||
UniqueName = organizationUniqueName,
|
||
FriendlyName = organizationFriendlyName,
|
||
SqlServerName = SqlServer,
|
||
SrsUrl = ReportingServer,
|
||
BaseCurrencyCode = baseCurrencyCode,
|
||
BaseCurrencyName = baseCurrencyName,
|
||
BaseCurrencySymbol = baseCurrencySymbol,
|
||
SqlCollation = organizationCollation,
|
||
State = Microsoft.Xrm.Sdk.Deployment.OrganizationState.Enabled
|
||
};
|
||
|
||
BeginCreateOrganizationRequest req = new BeginCreateOrganizationRequest
|
||
{
|
||
Organization = org
|
||
};
|
||
|
||
if (!String.IsNullOrEmpty(UserName))
|
||
{
|
||
req.SysAdminName = UserName;
|
||
}
|
||
|
||
BeginCreateOrganizationResponse resp = deploymentService.Execute(req) as BeginCreateOrganizationResponse;
|
||
|
||
if (resp == null)
|
||
throw new ArgumentException("BeginCreateOrganizationResponse is Null");
|
||
|
||
EntityInstanceId id = new EntityInstanceId();
|
||
id.Name = org.UniqueName;
|
||
|
||
Microsoft.Xrm.Sdk.Deployment.OrganizationState OperationState = Microsoft.Xrm.Sdk.Deployment.OrganizationState.Pending;
|
||
|
||
do
|
||
{
|
||
Thread.Sleep(30000);
|
||
try
|
||
{
|
||
Microsoft.Xrm.Sdk.Deployment.Organization getorg
|
||
= (Microsoft.Xrm.Sdk.Deployment.Organization)deploymentService.Retrieve(DeploymentEntityType.Organization, id);
|
||
OperationState = getorg.State;
|
||
}
|
||
catch { }
|
||
} while ((OperationState != Microsoft.Xrm.Sdk.Deployment.OrganizationState.Enabled) &&
|
||
(OperationState != Microsoft.Xrm.Sdk.Deployment.OrganizationState.Failed));
|
||
|
||
if (OperationState == Microsoft.Xrm.Sdk.Deployment.OrganizationState.Failed)
|
||
throw new ArgumentException("Create organization failed.");
|
||
|
||
|
||
try
|
||
{
|
||
OrganizationServiceProxy _serviceProxy = GetOrganizationProxy(organizationUniqueName);
|
||
|
||
string ldap = "";
|
||
|
||
Guid SysAdminGuid = RetrieveSystemUser(GetDomainName(initialUserDomainName), initialUserFirstName, initialUserLastName, CRMSysAdminRoleStr, _serviceProxy, ref ldap);
|
||
}
|
||
catch { }
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
HostedSolutionLog.LogError(ex);
|
||
EndLog("CheckCrmEnvironment", ret, CrmErrorCodes.CREATE_CRM_ORGANIZATION_GENERAL_ERROR, ex);
|
||
return ret;
|
||
|
||
}
|
||
|
||
EndLog("CheckCrmEnvironment");
|
||
|
||
return ret;
|
||
}
|
||
|
||
private string GetDomainName(string username)
|
||
{
|
||
string domain = ActiveDirectoryUtils.GetNETBIOSDomainName(ServerSettings.ADRootDomain);
|
||
string ret = string.Format(@"{0}\{1}", domain, username);
|
||
return ret;
|
||
}
|
||
|
||
public string[] GetSupportedCollationNames()
|
||
{
|
||
return GetSupportedCollationNamesInternal(SqlServer);
|
||
}
|
||
|
||
internal static string[] GetSupportedCollationNamesInternal(string SqlServer)
|
||
{
|
||
HostedSolutionLog.LogStart("GetSupportedCollationNamesInternal");
|
||
|
||
List<string> ret = new List<string>();
|
||
|
||
string databaseName = "MSCRM_CONFIG";
|
||
|
||
SqlConnection connection = null;
|
||
try
|
||
{
|
||
connection = new SqlConnection();
|
||
connection.ConnectionString =
|
||
string.Format("Server={1};Initial Catalog={0};Integrated Security=SSPI",
|
||
databaseName, SqlServer);
|
||
|
||
connection.Open();
|
||
|
||
string commandText = "select * from fn_helpcollations() where " +
|
||
"(name not like '%_WS') AND (name not like '%_KS') AND (name not like '%_100_%') " +
|
||
" AND (name not like 'SQL_%') " +
|
||
" order by name";
|
||
SqlCommand command = new SqlCommand(commandText, connection);
|
||
SqlDataReader reader = command.ExecuteReader();
|
||
|
||
while (reader.Read())
|
||
{
|
||
string name = reader["name"] as string;
|
||
ret.Add(name);
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
}
|
||
finally
|
||
{
|
||
if (connection != null)
|
||
connection.Dispose();
|
||
|
||
}
|
||
|
||
HostedSolutionLog.LogEnd("GetSupportedCollationNamesInternal");
|
||
return ret.ToArray();
|
||
}
|
||
|
||
public Currency[] GetCurrencyList()
|
||
{
|
||
return GetCurrencyListInternal();
|
||
}
|
||
|
||
private Currency[] GetCurrencyListInternal()
|
||
{
|
||
HostedSolutionLog.LogStart("GetCurrencyListInternal");
|
||
List<Currency> retList = new List<Currency>();
|
||
|
||
CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures & ~CultureTypes.NeutralCultures);
|
||
|
||
foreach (CultureInfo cultire in cultures)
|
||
{
|
||
try
|
||
{
|
||
RegionInfo Region = new RegionInfo(cultire.LCID);
|
||
|
||
Console.WriteLine(cultire.NativeName + " " + Region.CurrencyNativeName);
|
||
|
||
Currency currency = new Currency();
|
||
currency.RegionName = Region.NativeName;
|
||
currency.CurrencyName = Region.CurrencyNativeName;
|
||
currency.CurrencyCode = Region.ISOCurrencySymbol;
|
||
currency.CurrencySymbol = Region.CurrencySymbol;
|
||
retList.Add(currency);
|
||
|
||
}
|
||
catch
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
|
||
retList.Sort(delegate(Currency a, Currency b) { return a.RegionName.CompareTo(b.RegionName); });
|
||
|
||
HostedSolutionLog.LogEnd("GetCurrencyListInternal");
|
||
return retList.ToArray();
|
||
}
|
||
|
||
|
||
public ResultObject DeleteOrganization(Guid orgId)
|
||
{
|
||
return DeleteOrganizationInternal(orgId);
|
||
}
|
||
|
||
internal ResultObject DeleteOrganizationInternal(Guid orgId)
|
||
{
|
||
ResultObject res = StartLog<ResultObject>("DeleteOrganizationInternal");
|
||
|
||
|
||
res.IsSuccess = true;
|
||
try
|
||
{
|
||
Uri serviceUrl = new Uri(CRMServiceUrl);
|
||
|
||
DeploymentServiceClient deploymentService = Microsoft.Xrm.Sdk.Deployment.Proxy.ProxyClientHelper.CreateClient(serviceUrl);
|
||
|
||
EntityInstanceId i = new EntityInstanceId();
|
||
i.Id = orgId; //Organisation Id
|
||
|
||
Microsoft.Xrm.Sdk.Deployment.Organization org = (Microsoft.Xrm.Sdk.Deployment.Organization)deploymentService.Retrieve(DeploymentEntityType.Organization, i);
|
||
|
||
org.State = Microsoft.Xrm.Sdk.Deployment.OrganizationState.Disabled;
|
||
|
||
Microsoft.Xrm.Sdk.Deployment.UpdateRequest updateRequest = new Microsoft.Xrm.Sdk.Deployment.UpdateRequest();
|
||
updateRequest.Entity = org;
|
||
|
||
deploymentService.Execute(updateRequest);
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("DeleteOrganizationInternal", res, CrmErrorCodes.DELETE_CRM_ORGANIZATION_GENERAL_ERROR, ex);
|
||
return res;
|
||
|
||
}
|
||
|
||
|
||
EndLog("DeleteOrganizationInternal");
|
||
return res;
|
||
}
|
||
|
||
public override void DeleteServiceItems(ServiceProviderItem[] items)
|
||
{
|
||
foreach (ServiceProviderItem item in items)
|
||
{
|
||
try
|
||
{
|
||
if (item is Organization)
|
||
{
|
||
Organization org = item as Organization;
|
||
DeleteOrganization(org.CrmOrganizationId);
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.WriteError(String.Format("Error deleting '{0}' {1}", item.Name, item.GetType().Name), ex);
|
||
}
|
||
}
|
||
base.DeleteServiceItems(items);
|
||
|
||
}
|
||
|
||
private static void EndLog(string message, ResultObject res, string errorCode, Exception ex)
|
||
{
|
||
if (res != null)
|
||
{
|
||
res.IsSuccess = false;
|
||
|
||
if (!string.IsNullOrEmpty(errorCode))
|
||
res.ErrorCodes.Add(errorCode);
|
||
}
|
||
|
||
if (ex != null)
|
||
HostedSolutionLog.LogError(ex);
|
||
|
||
HostedSolutionLog.LogEnd(message);
|
||
}
|
||
|
||
private static void EndLog(string message, ResultObject res, string errorCode)
|
||
{
|
||
EndLog(message, res, errorCode, null);
|
||
}
|
||
|
||
private static void EndLog(string message, ResultObject res)
|
||
{
|
||
EndLog(message, res, null);
|
||
}
|
||
|
||
private static void EndLog(string message)
|
||
{
|
||
EndLog(message, null);
|
||
}
|
||
|
||
private static T StartLog<T>(string message) where T : ResultObject, new()
|
||
{
|
||
HostedSolutionLog.LogStart(message);
|
||
T res = new T();
|
||
res.IsSuccess = true;
|
||
return res;
|
||
}
|
||
|
||
public UserResult CreateCRMUser(OrganizationUser user, string orgName, Guid organizationId, Guid baseUnitId)
|
||
{
|
||
return CreateCRMUserInternal(user, orgName, organizationId, baseUnitId);
|
||
}
|
||
|
||
internal UserResult CreateCRMUserInternal(OrganizationUser user, string orgName, Guid organizationId, Guid businessUnitId)
|
||
{
|
||
UserResult res = StartLog<UserResult>("CreateCRMUserInternal");
|
||
|
||
try
|
||
{
|
||
if (user == null)
|
||
throw new ArgumentNullException("user");
|
||
|
||
if (string.IsNullOrEmpty(orgName))
|
||
throw new ArgumentNullException("orgName");
|
||
|
||
if (organizationId == Guid.Empty)
|
||
throw new ArgumentException("organizationId");
|
||
|
||
if (businessUnitId == Guid.Empty)
|
||
throw new ArgumentException("businessUnitId");
|
||
|
||
try
|
||
{
|
||
OrganizationServiceProxy _serviceProxy = GetOrganizationProxy(orgName);
|
||
|
||
|
||
string ldap = "";
|
||
Guid guid = RetrieveSystemUser(user.DomainUserName, user.FirstName, user.LastName, CRMSysAdminRoleStr, _serviceProxy, ref ldap);
|
||
|
||
user.CrmUserId = guid;
|
||
res.Value = user;
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("CreateCRMUserInternal", res, CrmErrorCodes.CANNOT_CREATE_CRM_USER, ex);
|
||
return res;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("CreateCRMUserInternal", res, CrmErrorCodes.CANNOT_CREATE_CRM_USER_GENERAL_ERROR, ex);
|
||
return res;
|
||
|
||
}
|
||
|
||
EndLog("CreateCRMUserInternal");
|
||
return res;
|
||
}
|
||
|
||
private static Guid CreateSystemUser(String userName, String firstName,
|
||
String lastName, String domain, String roleStr,
|
||
OrganizationServiceProxy serviceProxy, ref String ldapPath)
|
||
{
|
||
|
||
if (serviceProxy.ServiceConfiguration.AuthenticationType == AuthenticationProviderType.LiveId ||
|
||
serviceProxy.ServiceConfiguration.AuthenticationType == AuthenticationProviderType.OnlineFederation)
|
||
throw new Exception(String.Format("To run this sample, {0} {1} must be an active system user in your Microsoft Dynamics CRM Online organization.", firstName, lastName));
|
||
|
||
Guid userId = Guid.Empty;
|
||
|
||
Microsoft.Xrm.Sdk.Query.QueryExpression businessUnitQuery = new Microsoft.Xrm.Sdk.Query.QueryExpression
|
||
{
|
||
EntityName = BusinessUnit.EntityLogicalName,
|
||
ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet("businessunitid"),
|
||
Criteria =
|
||
{
|
||
Conditions =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.ConditionExpression("parentbusinessunitid",
|
||
Microsoft.Xrm.Sdk.Query.ConditionOperator.Null)
|
||
}
|
||
}
|
||
};
|
||
|
||
BusinessUnit defaultBusinessUnit = serviceProxy.RetrieveMultiple(
|
||
businessUnitQuery).Entities[0].ToEntity<BusinessUnit>();
|
||
|
||
// Retrieve the specified security role.
|
||
Role role = RetrieveRoleByName(serviceProxy, roleStr);
|
||
|
||
//Create a new system user.
|
||
SystemUser user = new SystemUser
|
||
{
|
||
DomainName = userName,
|
||
FirstName = firstName,
|
||
LastName = lastName,
|
||
BusinessUnitId = new EntityReference
|
||
{
|
||
LogicalName = BusinessUnit.EntityLogicalName,
|
||
Name = BusinessUnit.EntityLogicalName,
|
||
Id = defaultBusinessUnit.Id
|
||
}
|
||
};
|
||
userId = serviceProxy.Create(user);
|
||
|
||
// Assign the security role to the newly created Microsoft Dynamics CRM user.
|
||
AssociateRequest associate = new AssociateRequest()
|
||
{
|
||
Target = new EntityReference(SystemUser.EntityLogicalName, userId),
|
||
RelatedEntities = new EntityReferenceCollection()
|
||
{
|
||
new EntityReference(Role.EntityLogicalName, role.Id),
|
||
},
|
||
Relationship = new Relationship("systemuserroles_association")
|
||
};
|
||
serviceProxy.Execute(associate);
|
||
|
||
return userId;
|
||
}
|
||
|
||
|
||
public static Guid RetrieveSystemUser(String userName, String firstName,
|
||
String lastName, String roleStr, OrganizationServiceProxy serviceProxy,
|
||
ref String ldapPath)
|
||
{
|
||
String domain;
|
||
Guid userId = Guid.Empty;
|
||
|
||
if (serviceProxy == null)
|
||
throw new ArgumentNullException("serviceProxy");
|
||
|
||
if (String.IsNullOrWhiteSpace(userName))
|
||
throw new ArgumentNullException("UserName");
|
||
|
||
if (String.IsNullOrWhiteSpace(firstName))
|
||
throw new ArgumentNullException("FirstName");
|
||
|
||
if (String.IsNullOrWhiteSpace(lastName))
|
||
throw new ArgumentNullException("LastName");
|
||
|
||
if (String.IsNullOrWhiteSpace(roleStr))
|
||
throw new ArgumentNullException("Role");
|
||
|
||
// Obtain the current user's information.
|
||
Microsoft.Crm.Sdk.Messages.WhoAmIRequest who = new Microsoft.Crm.Sdk.Messages.WhoAmIRequest();
|
||
Microsoft.Crm.Sdk.Messages.WhoAmIResponse whoResp = (Microsoft.Crm.Sdk.Messages.WhoAmIResponse)serviceProxy.Execute(who);
|
||
Guid currentUserId = whoResp.UserId;
|
||
|
||
SystemUser currentUser =
|
||
serviceProxy.Retrieve(SystemUser.EntityLogicalName, currentUserId, new Microsoft.Xrm.Sdk.Query.ColumnSet("domainname")).ToEntity<SystemUser>();
|
||
|
||
// Extract the domain and create the LDAP object.
|
||
String[] userPath = currentUser.DomainName.Split(new char[] { '\\' });
|
||
if (userPath.Length > 1)
|
||
domain = userPath[0] + "\\";
|
||
else
|
||
domain = String.Empty;
|
||
|
||
// Create the system user in Microsoft Dynamics CRM if the user doesn't
|
||
// already exist.
|
||
Microsoft.Xrm.Sdk.Query.QueryExpression userQuery = new Microsoft.Xrm.Sdk.Query.QueryExpression
|
||
{
|
||
EntityName = SystemUser.EntityLogicalName,
|
||
ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet("systemuserid"),
|
||
Criteria =
|
||
{
|
||
FilterOperator = Microsoft.Xrm.Sdk.Query.LogicalOperator.Or,
|
||
Filters =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.FilterExpression
|
||
{
|
||
FilterOperator = Microsoft.Xrm.Sdk.Query.LogicalOperator.And,
|
||
Conditions =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.ConditionExpression("domainname", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, domain + userName)
|
||
}
|
||
},
|
||
new Microsoft.Xrm.Sdk.Query.FilterExpression
|
||
{
|
||
FilterOperator = Microsoft.Xrm.Sdk.Query.LogicalOperator.And,
|
||
Conditions =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.ConditionExpression("firstname", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, firstName),
|
||
new Microsoft.Xrm.Sdk.Query.ConditionExpression("lastname", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, lastName)
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
};
|
||
|
||
DataCollection<Entity> existingUsers = (DataCollection<Entity>)serviceProxy.RetrieveMultiple(userQuery).Entities;
|
||
|
||
SystemUser existingUser = null;
|
||
if (existingUsers.Count > 0)
|
||
existingUser = existingUsers[0].ToEntity<SystemUser>();
|
||
|
||
if (existingUser != null)
|
||
{
|
||
userId = existingUser.SystemUserId.Value;
|
||
|
||
// Check to make sure the user is assigned the correct role.
|
||
Role role = RetrieveRoleByName(serviceProxy, roleStr);
|
||
|
||
// Associate the user with the role when needed.
|
||
if (!UserInRole(serviceProxy, userId, role.Id))
|
||
{
|
||
AssociateRequest associate = new AssociateRequest()
|
||
{
|
||
Target = new EntityReference(SystemUser.EntityLogicalName, userId),
|
||
RelatedEntities = new EntityReferenceCollection()
|
||
{
|
||
new EntityReference(Role.EntityLogicalName, role.Id)
|
||
},
|
||
Relationship = new Relationship("systemuserroles_association")
|
||
};
|
||
serviceProxy.Execute(associate);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
userId = CreateSystemUser(userName, firstName, lastName, domain,
|
||
roleStr, serviceProxy, ref ldapPath);
|
||
}
|
||
|
||
return userId;
|
||
}
|
||
|
||
private static Role RetrieveRoleByName(OrganizationServiceProxy serviceProxy,
|
||
String roleSplitStr)
|
||
{
|
||
string[] RolesStr = roleSplitStr.Split(';');
|
||
|
||
foreach (string roleStr in RolesStr)
|
||
{
|
||
|
||
Microsoft.Xrm.Sdk.Query.QueryExpression roleQuery = new Microsoft.Xrm.Sdk.Query.QueryExpression
|
||
{
|
||
EntityName = Role.EntityLogicalName,
|
||
ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet("roleid"),
|
||
Criteria =
|
||
{
|
||
Conditions =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.ConditionExpression("name", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, roleStr)
|
||
}
|
||
}
|
||
};
|
||
|
||
DataCollection<Entity> roles = serviceProxy.RetrieveMultiple(roleQuery).Entities;
|
||
|
||
if (roles.Count > 0) return roles[0].ToEntity<Role>();
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
private static bool UserInRole(OrganizationServiceProxy serviceProxy,
|
||
Guid userId, Guid roleId)
|
||
{
|
||
// Establish a SystemUser link for a query.
|
||
Microsoft.Xrm.Sdk.Query.LinkEntity systemUserLink = new Microsoft.Xrm.Sdk.Query.LinkEntity()
|
||
{
|
||
LinkFromEntityName = SystemUserRoles.EntityLogicalName,
|
||
LinkFromAttributeName = "systemuserid",
|
||
LinkToEntityName = SystemUser.EntityLogicalName,
|
||
LinkToAttributeName = "systemuserid",
|
||
LinkCriteria =
|
||
{
|
||
Conditions =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.ConditionExpression(
|
||
"systemuserid", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, userId)
|
||
}
|
||
}
|
||
};
|
||
|
||
// Build the query.
|
||
Microsoft.Xrm.Sdk.Query.QueryExpression query = new Microsoft.Xrm.Sdk.Query.QueryExpression()
|
||
{
|
||
EntityName = Role.EntityLogicalName,
|
||
ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet("roleid"),
|
||
LinkEntities =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.LinkEntity()
|
||
{
|
||
LinkFromEntityName = Role.EntityLogicalName,
|
||
LinkFromAttributeName = "roleid",
|
||
LinkToEntityName = SystemUserRoles.EntityLogicalName,
|
||
LinkToAttributeName = "roleid",
|
||
LinkEntities = {systemUserLink}
|
||
}
|
||
},
|
||
Criteria =
|
||
{
|
||
Conditions =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.ConditionExpression("roleid", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, roleId)
|
||
}
|
||
}
|
||
};
|
||
|
||
// Retrieve matching roles.
|
||
EntityCollection ec = serviceProxy.RetrieveMultiple(query);
|
||
|
||
if (ec.Entities.Count > 0)
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
int GetOrganizationProxyTryCount = 5;
|
||
int GetOrganizationProxyTryTimeout = 30000;
|
||
|
||
private OrganizationServiceProxy GetOrganizationProxy(string orgName)
|
||
{
|
||
|
||
Uri OrganizationUri = GetOrganizationAddress(orgName);
|
||
|
||
OrganizationServiceProxy r = null;
|
||
|
||
bool success = false;
|
||
int tryItem = 0;
|
||
Exception exception = null;
|
||
|
||
while (!success)
|
||
{
|
||
|
||
try
|
||
{
|
||
// Set IServiceManagement for the current organization.
|
||
IServiceManagement<IOrganizationService> orgServiceManagement =
|
||
ServiceConfigurationFactory.CreateManagement<IOrganizationService>(
|
||
OrganizationUri);
|
||
|
||
r = new OrganizationServiceProxy(
|
||
orgServiceManagement,
|
||
GetUserLogonCredentials());
|
||
|
||
success = true;
|
||
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
Thread.Sleep(GetOrganizationProxyTryTimeout);
|
||
tryItem++;
|
||
if (tryItem >= GetOrganizationProxyTryCount)
|
||
{
|
||
exception = exc;
|
||
success = true;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
if (exception != null)
|
||
throw new ArgumentException(exception.ToString());
|
||
|
||
r.EnableProxyTypes();
|
||
|
||
return r;
|
||
}
|
||
|
||
protected virtual ClientCredentials GetUserLogonCredentials()
|
||
{
|
||
ClientCredentials credentials = new ClientCredentials();
|
||
|
||
if (String.IsNullOrEmpty(UserName))
|
||
{
|
||
credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
|
||
}
|
||
else
|
||
{
|
||
credentials.UserName.UserName = UserName;
|
||
credentials.UserName.Password = Password;
|
||
}
|
||
|
||
return credentials;
|
||
}
|
||
|
||
|
||
private DiscoveryServiceProxy GetDiscoveryProxy()
|
||
{
|
||
|
||
IServiceManagement<IDiscoveryService> serviceManagement =
|
||
ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(
|
||
new Uri(CRMDiscoveryUri));
|
||
|
||
ClientCredentials Credentials = GetUserLogonCredentials();
|
||
|
||
DiscoveryServiceProxy r = new DiscoveryServiceProxy(serviceManagement, Credentials);
|
||
|
||
return r;
|
||
}
|
||
|
||
|
||
public OrganizationDetailCollection DiscoverOrganizations(IDiscoveryService service)
|
||
{
|
||
if (service == null) throw new ArgumentNullException("service");
|
||
RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
|
||
RetrieveOrganizationsResponse orgResponse =
|
||
(RetrieveOrganizationsResponse)service.Execute(orgRequest);
|
||
|
||
return orgResponse.Details;
|
||
}
|
||
|
||
protected virtual Uri GetOrganizationAddress(string orgName)
|
||
{
|
||
string url = "https://" + ProviderSettings[Constants.AppRootDomain] + ":" + ProviderSettings[Constants.Port] + "/" + orgName + "/XRMServices/2011/Organization.svc";
|
||
|
||
try
|
||
{
|
||
|
||
using (DiscoveryServiceProxy serviceProxy = GetDiscoveryProxy())
|
||
{
|
||
// Obtain organization information from the Discovery service.
|
||
if (serviceProxy != null)
|
||
{
|
||
// Obtain information about the organizations that the system user belongs to.
|
||
OrganizationDetailCollection orgs = DiscoverOrganizations(serviceProxy);
|
||
|
||
for (int n = 0; n < orgs.Count; n++)
|
||
{
|
||
if (orgs[n].UniqueName == orgName)
|
||
{
|
||
// Return the organization Uri.
|
||
return new System.Uri(orgs[n].Endpoints[EndpointType.OrganizationService]);
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
catch { }
|
||
|
||
return new Uri(url);
|
||
|
||
}
|
||
|
||
|
||
internal CRMBusinessUnitsResult GetOrganizationBusinessUnitsInternal(Guid organizationId, string orgName)
|
||
{
|
||
CRMBusinessUnitsResult res = StartLog<CRMBusinessUnitsResult>("GetOrganizationBusinessUnitsInternal");
|
||
|
||
try
|
||
{
|
||
if (organizationId == Guid.Empty)
|
||
throw new ArgumentException("organizationId");
|
||
|
||
if (string.IsNullOrEmpty(orgName))
|
||
throw new ArgumentNullException("orgName");
|
||
|
||
OrganizationServiceProxy serviceProxy;
|
||
|
||
try
|
||
{
|
||
serviceProxy = GetOrganizationProxy(orgName);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetOrganizationBusinessUnitsInternal", res, CrmErrorCodes.CANNOT_GET_CRM_SERVICE, ex);
|
||
return res;
|
||
}
|
||
|
||
DataCollection<Entity> BusinessUnits;
|
||
|
||
try
|
||
{
|
||
|
||
Microsoft.Xrm.Sdk.Query.QueryExpression businessUnitQuery = new Microsoft.Xrm.Sdk.Query.QueryExpression
|
||
{
|
||
EntityName = BusinessUnit.EntityLogicalName,
|
||
ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet(new string[] { "businessunitid", "name" }),
|
||
Criteria =
|
||
{
|
||
Conditions =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.ConditionExpression("parentbusinessunitid",
|
||
Microsoft.Xrm.Sdk.Query.ConditionOperator.Null)
|
||
}
|
||
}
|
||
};
|
||
|
||
BusinessUnits = serviceProxy.RetrieveMultiple(
|
||
businessUnitQuery).Entities;
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetOrganizationBusinessUnitsInternal", res, CrmErrorCodes.CANNOT_GET_CRM_BUSINESS_UNITS, ex);
|
||
return res;
|
||
}
|
||
|
||
List<CRMBusinessUnit> businessUnits = new List<CRMBusinessUnit>();
|
||
|
||
try
|
||
{
|
||
for (int i = 0; i < BusinessUnits.Count; i++)
|
||
{
|
||
BusinessUnit bu = BusinessUnits[i].ToEntity<BusinessUnit>();
|
||
|
||
CRMBusinessUnit unit = new CRMBusinessUnit();
|
||
unit.BusinessUnitId = (Guid)bu.BusinessUnitId;
|
||
unit.BusinessUnitName = bu.Name;
|
||
|
||
if (unit.BusinessUnitName == null)
|
||
unit.BusinessUnitName = "default";
|
||
|
||
businessUnits.Add(unit);
|
||
|
||
}
|
||
|
||
res.Value = businessUnits;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetOrganizationBusinessUnitsInternal", res, CrmErrorCodes.CANNOT_FILL_BASE_UNITS_COLLECTION,
|
||
ex);
|
||
return res;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetOrganizationBusinessUnitsInternal", res, CrmErrorCodes.GET_ORGANIZATION_BUSINESS_UNITS_GENERAL_ERROR,
|
||
ex);
|
||
return res;
|
||
|
||
}
|
||
|
||
EndLog("GetOrganizationBusinessUnitsInternal");
|
||
return res;
|
||
|
||
}
|
||
|
||
public CRMBusinessUnitsResult GetOrganizationBusinessUnits(Guid organizationId, string orgName)
|
||
{
|
||
return GetOrganizationBusinessUnitsInternal(organizationId, orgName);
|
||
}
|
||
|
||
public CrmRolesResult GetAllCrmRoles(string orgName, Guid businessUnitId)
|
||
{
|
||
return GetAllCrmRolesInternal(orgName, businessUnitId);
|
||
}
|
||
|
||
public CrmRolesResult GetCrmUserRoles(string orgName, Guid userId)
|
||
{
|
||
return GetCrmUserRolesInternal(userId, orgName);
|
||
}
|
||
|
||
public EntityCollection GetUserRoles(Guid userId, string orgName)
|
||
{
|
||
OrganizationServiceProxy serviceProxy = GetOrganizationProxy(orgName);
|
||
|
||
// Establish a SystemUser link for a query.
|
||
Microsoft.Xrm.Sdk.Query.LinkEntity systemUserLink = new Microsoft.Xrm.Sdk.Query.LinkEntity()
|
||
{
|
||
LinkFromEntityName = SystemUserRoles.EntityLogicalName,
|
||
LinkFromAttributeName = "systemuserid",
|
||
LinkToEntityName = SystemUser.EntityLogicalName,
|
||
LinkToAttributeName = "systemuserid",
|
||
LinkCriteria =
|
||
{
|
||
Conditions =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.ConditionExpression(
|
||
"systemuserid", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, userId)
|
||
}
|
||
}
|
||
};
|
||
|
||
// Build the query.
|
||
Microsoft.Xrm.Sdk.Query.QueryExpression query = new Microsoft.Xrm.Sdk.Query.QueryExpression()
|
||
{
|
||
EntityName = Role.EntityLogicalName,
|
||
ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet("roleid"),
|
||
LinkEntities =
|
||
{
|
||
new Microsoft.Xrm.Sdk.Query.LinkEntity()
|
||
{
|
||
LinkFromEntityName = Role.EntityLogicalName,
|
||
LinkFromAttributeName = "roleid",
|
||
LinkToEntityName = SystemUserRoles.EntityLogicalName,
|
||
LinkToAttributeName = "roleid",
|
||
LinkEntities = {systemUserLink}
|
||
}
|
||
}
|
||
};
|
||
|
||
// Retrieve matching roles.
|
||
EntityCollection relations = serviceProxy.RetrieveMultiple(query);
|
||
|
||
return relations;
|
||
}
|
||
|
||
internal CrmRolesResult GetCrmUserRolesInternal(Guid userId, string orgName)
|
||
{
|
||
CrmRolesResult res = StartLog<CrmRolesResult>("GetCrmUserRolesInternal");
|
||
|
||
|
||
try
|
||
{
|
||
EntityCollection relations;
|
||
|
||
if (userId == Guid.Empty)
|
||
throw new ArgumentException("userId");
|
||
|
||
if (string.IsNullOrEmpty(orgName))
|
||
throw new ArgumentNullException("orgName");
|
||
|
||
try
|
||
{
|
||
relations = GetUserRoles(userId, orgName);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetCrmUserRolesInternal", res, CrmErrorCodes.CANNOT_GET_CRM_USER_ROLES, ex);
|
||
return res;
|
||
}
|
||
|
||
try
|
||
{
|
||
res.Value = FillCrmRoles(relations, true, Guid.Empty);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetCrmUserRolesInternal", res, CrmErrorCodes.CANNOT_FILL_ROLES_COLLECTION, ex);
|
||
return res;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetCrmUserRolesInternal", res, CrmErrorCodes.GET_CRM_USER_ROLE_GENERAL_ERROR, ex);
|
||
return res;
|
||
}
|
||
|
||
EndLog("GetCrmUserRolesInternal");
|
||
return res;
|
||
}
|
||
|
||
private static List<CrmRole> FillCrmRoles(EntityCollection entities, bool isUserRole, Guid businessUnitId)
|
||
{
|
||
List<CrmRole> res = new List<CrmRole>();
|
||
|
||
foreach (Entity current in entities.Entities)
|
||
{
|
||
Role role = current.ToEntity<Role>();
|
||
|
||
if (role == null) continue;
|
||
|
||
if (businessUnitId != Guid.Empty)
|
||
{
|
||
if (businessUnitId != role.BusinessUnitId.Id)
|
||
continue;
|
||
}
|
||
|
||
CrmRole crmRole = new CrmRole();
|
||
crmRole.IsCurrentUserRole = isUserRole;
|
||
crmRole.RoleId = (Guid)role.RoleId;
|
||
crmRole.RoleName = role.Name;
|
||
|
||
res.Add(crmRole);
|
||
}
|
||
|
||
return res;
|
||
}
|
||
|
||
|
||
private static List<CrmRole> FillCrmRoles(EntityCollection entities, Guid businessUnitId)
|
||
{
|
||
return FillCrmRoles(entities, false, businessUnitId);
|
||
}
|
||
|
||
internal CrmRolesResult GetAllCrmRolesInternal(string orgName, Guid businessUnitId)
|
||
{
|
||
CrmRolesResult res = StartLog<CrmRolesResult>("GetAllCrmRoles");
|
||
|
||
try
|
||
{
|
||
if (string.IsNullOrEmpty(orgName))
|
||
throw new ArgumentNullException("orgName");
|
||
|
||
EntityCollection roles;
|
||
try
|
||
{
|
||
OrganizationServiceProxy serviceProxy = GetOrganizationProxy(orgName);
|
||
|
||
Microsoft.Xrm.Sdk.Query.QueryExpression roleQuery = new Microsoft.Xrm.Sdk.Query.QueryExpression
|
||
{
|
||
EntityName = Role.EntityLogicalName,
|
||
ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet(new string[] { "roleid", "name", "businessunitid" }),
|
||
};
|
||
|
||
roles = serviceProxy.RetrieveMultiple(roleQuery);
|
||
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetAllCrmRoles", res, CrmErrorCodes.CANNOT_GET_ALL_CRM_ROLES, ex);
|
||
return res;
|
||
}
|
||
|
||
try
|
||
{
|
||
List<CrmRole> crmRoles = FillCrmRoles(roles, businessUnitId);
|
||
res.Value = crmRoles;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetAllCrmRoles", res, CrmErrorCodes.CANNOT_FILL_ROLES_COLLECTION, ex);
|
||
return res;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetAllCrmRoles", res, CrmErrorCodes.GET_ALL_CRM_ROLES_GENERAL_ERROR, ex);
|
||
return res;
|
||
}
|
||
|
||
EndLog("GetAllCrmRoles");
|
||
return res;
|
||
}
|
||
|
||
public ResultObject SetUserRoles(string orgName, Guid userId, Guid[] roles)
|
||
{
|
||
return SetUserRolesInternal(orgName, userId, roles);
|
||
}
|
||
|
||
internal ResultObject SetUserRolesInternal(string orgName, Guid userId, Guid[] roles)
|
||
{
|
||
CrmRolesResult res = StartLog<CrmRolesResult>("SetUserRolesInternal");
|
||
|
||
try
|
||
{
|
||
if (string.IsNullOrEmpty(orgName))
|
||
throw new ArgumentNullException("orgName");
|
||
|
||
if (userId == Guid.Empty)
|
||
throw new ArgumentException("userId");
|
||
|
||
if (roles == null)
|
||
throw new ArgumentNullException("roles");
|
||
|
||
OrganizationServiceProxy serviceProxy = GetOrganizationProxy(orgName);
|
||
|
||
|
||
CrmRolesResult tmpRoles = GetCrmUserRoles(orgName, userId);
|
||
res.ErrorCodes.AddRange(tmpRoles.ErrorCodes);
|
||
|
||
if (!tmpRoles.IsSuccess)
|
||
return res;
|
||
|
||
List<Guid> remRoles = new List<Guid>();
|
||
|
||
for (int i = 0; i < tmpRoles.Value.Count; i++)
|
||
{
|
||
if (Array.Find(roles, delegate(Guid current) { return current == tmpRoles.Value[i].RoleId; }) == Guid.Empty)
|
||
{
|
||
remRoles.Add(tmpRoles.Value[i].RoleId);
|
||
}
|
||
}
|
||
|
||
try
|
||
{
|
||
DisassociateRequest removeRole = new DisassociateRequest()
|
||
{
|
||
Target = new EntityReference(SystemUser.EntityLogicalName, userId),
|
||
RelatedEntities = new EntityReferenceCollection(),
|
||
Relationship = new Relationship("systemuserroles_association")
|
||
};
|
||
|
||
for (int i = 0; i < remRoles.Count; i++)
|
||
removeRole.RelatedEntities.Add(new EntityReference(Role.EntityLogicalName, remRoles[i]));
|
||
|
||
serviceProxy.Execute(removeRole);
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("SetUserRolesInternal", res, CrmErrorCodes.CANNOT_REMOVE_CRM_USER_ROLES, ex);
|
||
return res;
|
||
}
|
||
|
||
|
||
try
|
||
{
|
||
// Assign the security role to the newly created Microsoft Dynamics CRM user.
|
||
AssociateRequest associate = new AssociateRequest()
|
||
{
|
||
Target = new EntityReference(SystemUser.EntityLogicalName, userId),
|
||
RelatedEntities = new EntityReferenceCollection(),
|
||
Relationship = new Relationship("systemuserroles_association")
|
||
};
|
||
|
||
for (int i = 0; i < roles.Length; i++)
|
||
{
|
||
bool find = false;
|
||
foreach (CrmRole current in tmpRoles.Value)
|
||
{
|
||
if (current.RoleId == roles[i])
|
||
find = true;
|
||
}
|
||
if (find) continue;
|
||
|
||
associate.RelatedEntities.Add(new EntityReference(Role.EntityLogicalName, roles[i]));
|
||
}
|
||
|
||
serviceProxy.Execute(associate);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("SetUserRolesInternal", res, CrmErrorCodes.CANNOT_ASSIGN_CRM_USER_ROLES, ex);
|
||
return res;
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("SetUserRolesInternal", res, CrmErrorCodes.CANNOT_SET_CRM_USER_ROLES_GENERAL_ERROR, ex);
|
||
return res;
|
||
}
|
||
|
||
|
||
EndLog("SetUserRolesInternal");
|
||
return res;
|
||
|
||
}
|
||
|
||
|
||
public CrmUserResult GetCrmUserById(Guid crmUserId, string orgName)
|
||
{
|
||
return GetCrmUserByIdInternal(crmUserId, orgName);
|
||
}
|
||
|
||
internal CrmUserResult GetCrmUserByIdInternal(Guid crmUserId, string orgName)
|
||
{
|
||
CrmUserResult ret = StartLog<CrmUserResult>("GetCrmUserByIdInternal");
|
||
|
||
try
|
||
{
|
||
if (crmUserId == Guid.Empty)
|
||
throw new ArgumentNullException("crmUserId");
|
||
|
||
if (string.IsNullOrEmpty(orgName))
|
||
throw new ArgumentNullException("orgName");
|
||
|
||
OrganizationServiceProxy serviceProxy = GetOrganizationProxy(orgName);
|
||
|
||
SystemUser retruveUser =
|
||
serviceProxy.Retrieve(SystemUser.EntityLogicalName, crmUserId, new Microsoft.Xrm.Sdk.Query.ColumnSet("domainname", "businessunitid", "accessmode", "isdisabled")).ToEntity<SystemUser>();
|
||
|
||
CrmUser user = null;
|
||
|
||
if (retruveUser != null)
|
||
{
|
||
user = new CrmUser();
|
||
user.BusinessUnitId = retruveUser.BusinessUnitId.Id;
|
||
user.CRMUserId = retruveUser.SystemUserId.Value;
|
||
user.ClientAccessMode = (CRMUserAccessMode)retruveUser.AccessMode.Value;
|
||
user.IsDisabled = (bool)retruveUser.IsDisabled;
|
||
|
||
ret.Value = user;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetCrmUserByIdInternal", ret, CrmErrorCodes.CANONT_GET_CRM_USER_BY_ID, ex);
|
||
return ret;
|
||
}
|
||
|
||
EndLog("GetCrmUserByIdInternal");
|
||
return ret;
|
||
}
|
||
|
||
|
||
internal CrmUserResult GetCrmUserByDomainNameInternal(string domainName, string orgName)
|
||
{
|
||
CrmUserResult ret = StartLog<CrmUserResult>("GetCrmUserByDomainNameInternal");
|
||
|
||
try
|
||
{
|
||
if (string.IsNullOrEmpty(domainName))
|
||
throw new ArgumentNullException("domainName");
|
||
|
||
if (string.IsNullOrEmpty(orgName))
|
||
throw new ArgumentNullException("orgName");
|
||
|
||
|
||
OrganizationServiceProxy serviceProxy = GetOrganizationProxy(orgName);
|
||
|
||
Microsoft.Xrm.Sdk.Query.QueryExpression usereQuery = new Microsoft.Xrm.Sdk.Query.QueryExpression
|
||
{
|
||
EntityName = SystemUser.EntityLogicalName,
|
||
ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet("domainname", "businessunitid", "accessmode", "isdisabled", "systemuserid"),
|
||
};
|
||
|
||
EntityCollection users = serviceProxy.RetrieveMultiple(usereQuery);
|
||
|
||
foreach (Entity entityuser in users.Entities)
|
||
{
|
||
SystemUser sysuser = entityuser.ToEntity<SystemUser>();
|
||
|
||
if (sysuser == null) continue;
|
||
if (sysuser.DomainName != domainName) continue;
|
||
|
||
CrmUser user = new CrmUser();
|
||
user.BusinessUnitId = sysuser.BusinessUnitId.Id;
|
||
user.CRMUserId = sysuser.SystemUserId.Value;
|
||
user.ClientAccessMode = (CRMUserAccessMode)sysuser.AccessMode.Value;
|
||
user.IsDisabled = sysuser.IsDisabled.Value;
|
||
ret.Value = user;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("GetCrmUserByDomainNameInternal", ret, CrmErrorCodes.CANONT_GET_CRM_USER_BY_DOMAIN_NAME, ex);
|
||
return ret;
|
||
}
|
||
|
||
EndLog("GetCrmUserByDomainNameInternal");
|
||
return ret;
|
||
}
|
||
|
||
public CrmUserResult GetCrmUserByDomainName(string domainName, string orgName)
|
||
{
|
||
return GetCrmUserByDomainNameInternal(domainName, orgName);
|
||
}
|
||
|
||
|
||
private static Guid GetFetureId(string name)
|
||
{
|
||
if (string.IsNullOrEmpty(name))
|
||
throw new ArgumentNullException("name");
|
||
|
||
return Guid.Empty;
|
||
}
|
||
|
||
|
||
public ResultObject ChangeUserState(bool disable, string orgName, Guid crmUserId)
|
||
{
|
||
return ChangeUserStateInternal(disable, orgName, crmUserId);
|
||
}
|
||
|
||
|
||
internal ResultObject ChangeUserStateInternal(bool disable, string orgName, Guid crmUserId)
|
||
{
|
||
ResultObject res = StartLog<ResultObject>("ChangeUserStateInternal");
|
||
|
||
res.IsSuccess = true;
|
||
try
|
||
{
|
||
if (crmUserId == Guid.Empty)
|
||
throw new ArgumentNullException("crmUserId");
|
||
|
||
if (string.IsNullOrEmpty(orgName))
|
||
throw new ArgumentNullException("orgName");
|
||
|
||
OrganizationServiceProxy serviceProxy = GetOrganizationProxy(orgName);
|
||
|
||
// Retrieve a user.
|
||
SystemUser user = serviceProxy.Retrieve(SystemUser.EntityLogicalName,
|
||
crmUserId, new Microsoft.Xrm.Sdk.Query.ColumnSet(new String[] { "systemuserid", "firstname", "lastname" })).ToEntity<SystemUser>();
|
||
|
||
if (user != null)
|
||
{
|
||
Microsoft.Crm.Sdk.Messages.SetStateRequest request = new Microsoft.Crm.Sdk.Messages.SetStateRequest()
|
||
{
|
||
EntityMoniker = user.ToEntityReference(),
|
||
|
||
// Required by request but always valued at -1 in this context.
|
||
Status = new OptionSetValue(-1),
|
||
|
||
// Sets the user to disabled.
|
||
State = disable ? new OptionSetValue(-1) : new OptionSetValue(0)
|
||
};
|
||
|
||
serviceProxy.Execute(request);
|
||
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EndLog("ChangeUserStateInternal", res, CrmErrorCodes.CANNOT_CHANGE_USER_STATE, ex);
|
||
return res;
|
||
}
|
||
|
||
|
||
EndLog("ChangeUserStateInternal");
|
||
return res;
|
||
}
|
||
|
||
|
||
public override bool IsInstalled()
|
||
{
|
||
string value = string.Empty;
|
||
try
|
||
{
|
||
RegistryKey root = Registry.LocalMachine;
|
||
RegistryKey rk = root.OpenSubKey("SOFTWARE\\Microsoft\\MSCRM");
|
||
|
||
if (rk == null)
|
||
rk = root.OpenSubKey("SOFTWARE\\Wow6432Node\\Microsoft\\MSCRM");
|
||
|
||
if (rk != null)
|
||
{
|
||
value = (string)rk.GetValue("CRM_Server_Version", null);
|
||
rk.Close();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.WriteError(ex);
|
||
}
|
||
|
||
return value.StartsWith("5.");
|
||
}
|
||
|
||
}
|
||
|
||
}
|