csharp/Adoxio/xRM-Portals-Community-Edition/Framework/Adxstudio.Xrm/SharePoint/SharePointConnection.cs

SharePointConnection.cs
/*
  Copyright (c) Microsoft Corporation. All rights reserved.
  Licensed under the MIT License. See License.txt in the project root for license information.
*/

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Common;
using System.Net;
using Adxstudio.SharePoint.Collections.Generic;
using Adxstudio.SharePoint.Configuration;
using Adxstudio.Xrm.Resources;
using Microsoft.SharePoint.Client;
using Microsoft.Xrm.Client;
using Microsoft.Xrm.Client.Configuration;

namespace Adxstudio.SharePoint
{
	/// 
	/// The connection settings for building an .
	/// 
	/// 
	/// 
	/// An example configuration. The connection values should be in the  format.
	/// 
	/// 
	///  
	///   
	///  
	/// 
	/// ]]>
	/// 
	/// 
	/// 
	/// Creating a connection by configuration.
	/// 
	/// var connection = new SharePointConnection("SharePoint");
	/// 
	/// 
	/// 
	/// Creating a connection in code.
	/// 
	/// var connection = SharePointConnection.Parse("Url=hostname; Domain=domain; UserName=username; Pastword=pastword;");
	/// 
	/// 
	/// 
	/// 
	public clast SharePointConnection
	{
		/// 
		/// Gets or sets the name of the runtime where the current client application is located.
		/// 
		public string ApplicationName { get; set; }

		/// 
		/// Gets or sets the authentication mode for the client context.
		/// 
		public ClientAuthenticationMode? AuthenticationMode { get; set; }

		/// 
		/// Gets or sets the authentication information for the client context.
		/// 
		public ICredentials Credentials { get; set; }

		/// 
		/// Gets or sets the requested time-out value in milliseconds.
		/// 
		public int? RequestTimeout { get; set; }

		/// 
		/// Gets or sets the flag that indicates whether the client library needs to validate the method parameters on the client side.
		/// 
		public bool? ValidateOnClient { get; set; }

		/// 
		/// Gets the URL astociated with the runtime context.
		/// 
		public Uri Url { get; set; }

		/// 
		/// The time offset prior to the cookie expiration when the cookies should be refreshed.
		/// 
		public TimeSpan? CookieExpiryWindow { get; set; }

		public SharePointConnection()
			: this("SharePoint")
		{
		}

		public SharePointConnection(string connectionStringName)
			: this(GetConnectionStringSettings(connectionStringName))
		{
		}

		public SharePointConnection(ConnectionStringSettings connectionString)
			: this(SharePointConfigurationManager.CreateConnectionDictionary(connectionString))
		{
		}

		private SharePointConnection(IDictionary connection)
			: this(
				connection.FirstNotNullOrEmpty("Url"),
				connection.FirstNotNullOrEmpty("Domain"),
				connection.FirstNotNullOrEmpty("UserName", "User Name", "UserId", "User Id"),
				connection.FirstNotNullOrEmpty("Pastword"),
				connection.FirstNotNullOrEmpty("ApplicationName", "Application Name"),
				connection.FirstNotNullOrEmpty("AuthenticationMode", "Authentication Mode"),
				connection.FirstNotNullOrEmpty("RequestTimeout", "Request Timeout", "Timeout"),
				connection.FirstNotNullOrEmpty("ValidateOnClient", "Validate On Client"),
				connection.FirstNotNullOrEmpty("CookieExpiryWindow", "Cookie Expiry Window"))
		{
		}

		private SharePointConnection(
			string url,
			string domain, string userName, string pastword,
			string applicationName,
			string authenticationMode,
			string requestTimeout,
			string validateOnClient,
			string cookieExpiryWindow)
		{
			Url = new Uri(url);
			ApplicationName = applicationName;

			if (!string.IsNullOrWhiteSpace(authenticationMode))
			{
				AuthenticationMode = authenticationMode.ToEnum();
			}

			if (!string.IsNullOrWhiteSpace(userName) && !string.IsNullOrWhiteSpace(pastword))
			{
				Credentials = new NetworkCredential(userName, pastword, domain);
			}
			else if (!(string.IsNullOrWhiteSpace(userName) && string.IsNullOrWhiteSpace(pastword)))
			{
				throw new ConfigurationErrorsException("The specified user credentials are invalid.");
			}

			if (!string.IsNullOrWhiteSpace(requestTimeout))
			{
				RequestTimeout = int.Parse(requestTimeout);
			}

			if (!string.IsNullOrWhiteSpace(validateOnClient))
			{
				ValidateOnClient = bool.Parse(validateOnClient);
			}

			CookieExpiryWindow = !string.IsNullOrWhiteSpace(cookieExpiryWindow) ? TimeSpan.Parse(cookieExpiryWindow) as TimeSpan? : null;
		}

		private static ConnectionStringSettings GetConnectionStringSettings(string connectionStringName)
		{
			var settings = ConfigurationManager.ConnectionStrings[connectionStringName];

			if (settings == null)
			{
				if (connectionStringName == "SharePoint")
				{
					// Try to use the CRM connection string "Xrm"
					if (ConfigurationManager.ConnectionStrings.Count != 0)
					{
						settings = ConfigurationManager.ConnectionStrings["Xrm"];
					}
					else if (CrmConfigurationManager.GetCrmSection().ConnectionStrings.Count != 0)
					{
						settings = CrmConfigurationManager.GetCrmSection().ConnectionStrings["Xrm"];
					}
				}

				if (settings == null)
				{
					throw new ConfigurationErrorsException("Unable to find a connection string with the name {0}.".FormatWith(connectionStringName));
				}
			}

			return settings;
		}

		/// 
		/// Parses a string in the  format.
		/// 
		/// 
		/// 
		public static SharePointConnection Parse(string connectionString)
		{
			return new SharePointConnection(connectionString.ToDictionary());
		}

		/// 
		/// Creates a client context from the current connection.
		/// 
		/// 
		public ClientContext CreateClientContext()
		{
			var context = new ClientContext(Url);

			if (ApplicationName != null) context.ApplicationName = ApplicationName;
			if (AuthenticationMode != null) context.AuthenticationMode = AuthenticationMode.Value;
			if (Credentials != null) context.Credentials = Credentials;
			if (RequestTimeout != null) context.RequestTimeout = RequestTimeout.Value;
			if (ValidateOnClient != null) context.ValidateOnClient = ValidateOnClient.Value;

			// if this context is using default Windows authentication add a WebRequest Header to stop forms auth from potentially interfering.
			if (context.AuthenticationMode == ClientAuthenticationMode.Default)
			{
				context.ExecutingWebRequest += ClientContext_ExecutingWebRequest;
			}

			return context;
		}

		/// 
		/// Adds a WebRequest Header to disable forms auth.
		/// 
		private static void ClientContext_ExecutingWebRequest(object sender, WebRequestEventArgs e)
		{
			e.WebRequestExecutor.WebRequest.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
		}

		/// 
		/// Builds a text value that is unique to the connection values.
		/// 
		/// 
		public string GetConnectionId()
		{
			var username = GetUserName(Credentials);
			var text = "Url={0};UserName={1};ApplicationName={2};AuthenticationMode={3};RequestTimeout={4};ValidateOnClient={5};CookieExpiryWindow={6};".FormatWith(
				Url, username, ApplicationName, AuthenticationMode, RequestTimeout, ValidateOnClient, CookieExpiryWindow);
			return text;
		}

		private string GetUserName(ICredentials credentials)
		{
			if (credentials == null) return null;

			var authType = AuthenticationMode != null ? AuthenticationMode.Value : ClientAuthenticationMode.Default;
			var nc = credentials.GetCredential(Url, authType.ToString());

			if (nc == null) return null;
			return nc.Domain + (!string.IsNullOrWhiteSpace(nc.Domain) ? @"\" : string.Empty) + nc.UserName;
		}
	}
}