using System; using System.Collections; using System.Text; using CMS.EventLog; using CMS.GlobalHelper; using CMS.OnlineMarketing; using CMS.SalesForce; using CMS.SalesForce.RestContract; using CMS.SettingsProvider; /// /// Guides the user through the process of authorizing access to SalesForce organization. /// public partial class CMSModules_ContactManagement_Pages_Tools_SalesForce_AuthorizationSetup : CMSSalesForceDialogPage { #region "Private members" private OrganizationCredentials mCredentials; private string mSourceCredentialsHiddenFieldClientId; private string mSourceMessageLabelClientId; private string mSourceUrlScheme; private int mSourceUrlPort; private string mSourceSiteName; #endregion #region "Protected properties" protected OrganizationCredentials Credentials { get { return mCredentials; } } protected string SourceCredentialsHiddenFieldClientId { get { return mSourceCredentialsHiddenFieldClientId; } } protected string SourceMessageLabelClientId { get { return mSourceMessageLabelClientId; } } protected string SourceUrlScheme { get { return mSourceUrlScheme; } } protected int SourceUrlPort { get { return mSourceUrlPort; } } protected string SourceSiteName { get { return mSourceSiteName; } } protected string RedirectUrl { get { Uri currentUrl = URLHelper.Url; if (ValidationHelper.GetBoolean(SettingsHelper.AppSettings["CMSSalesForceHttpCallbackEnabled"], false)) { UriBuilder builder = new UriBuilder { Scheme = "http", Host = currentUrl.Host, Path = currentUrl.AbsolutePath }; if (currentUrl.Port != 80) { builder.Port = currentUrl.Port; } return builder.Uri.ToString(); } else { UriBuilder builder = new UriBuilder { Scheme = "https", Host = currentUrl.Host, Path = currentUrl.AbsolutePath }; return builder.Uri.ToString(); } } } protected string ParametersId { get { string value = QueryHelper.GetString("pid", null); if (String.IsNullOrEmpty(value)) { value = QueryHelper.GetString("state", null); } return value; } } #endregion #region "Life-cycle methods" protected override void OnInit(EventArgs e) { base.OnInit(e); ScriptHelper.RegisterWOpenerScript(Page); ScriptHelper.RegisterJQuery(Page); Page.ClientScript.GetPostBackEventReference(ConfirmButton, String.Empty); CurrentMaster.Title.TitleText = GetString("sf.authorization.title"); CurrentMaster.Title.TitleImage = GetImageUrl("Objects/OM_Account/object.png"); CurrentMaster.HeadElements.Text += @""; ConfirmButton.Click += new EventHandler(ConfirmButton_Click); HelpImage.Src = GetImageUrl("General/HelpSmall.png"); } protected void Page_Load(object sender, EventArgs e) { try { RestoreParameters(); if (RequestHelper.IsPostBack() && Page.Request.Params["__EVENTTARGET"] == "SaveButton") { // The access to the Settings page was lost, it might happen as the Internet Explorer opens the target URL of SalesForce redirection in a new window. if (CurrentUser.IsGlobalAdministrator) { // The current user is a global administrator, so it is safe to proceed. // Without this check there is a security vulnerability as any CMS Desk user could choose a site and authorize access to his or her Sales Cloud organization. string name = "CMSSalesForceCredentials"; if (!String.IsNullOrEmpty(SourceSiteName)) { name = String.Format("{0}.{1}", SourceSiteName, name); } CloseDialog(GetString("sf.authorization.partialsuccess")); SettingsKeyProvider.SetValue(name, CredentialsHiddenField.Value); CredentialsHiddenField.Value = String.Empty; } } else { RedirectUrlLiteral.Text = HTMLHelper.HTMLEncode(RedirectUrl); string authorizationCode = QueryHelper.GetString("code", null); if (!String.IsNullOrEmpty(authorizationCode)) { SalesForceAuthorizationHelper authorizationHelper = new SalesForceAuthorizationHelper(Credentials.ClientId, Credentials.ClientSecret, RedirectUrl); GetAuthenticationTokensResponse response = authorizationHelper.GetAuthenticationTokens(authorizationCode); Identity identity = authorizationHelper.GetIdentity(response); Credentials.RefreshToken = response.RefreshToken; Credentials.OrganizationBaseUrl = response.InstanceBaseUrl; Credentials.UserName = identity.UserName; Credentials.OrganizationName = GetOrganizationName(Credentials, identity.OrganizationId); StoreParameters(); if (URLHelper.Url.Scheme != SourceUrlScheme) { RedirectToScheme(SourceUrlScheme, SourceUrlPort); } else { CloseDialog(GetString("sf.authorization.success")); } } else { string state = QueryHelper.GetString("state", null); if (!String.IsNullOrEmpty(state)) { CloseDialog(GetString("sf.authorization.success")); } } } } catch (Exception exception) { HandleError(exception); } } #endregion #region "Control event methods" protected void ConfirmButton_Click(object sender, EventArgs e) { if (String.IsNullOrEmpty(ClientIdentifierTextBox.Text) || String.IsNullOrEmpty(ClientSecretTextBox.Text)) { SalesForceError.Report(GetString("sf.authorization.missingconsumerinput")); } else { Credentials.ClientId = ClientIdentifierTextBox.Text; Credentials.ClientSecret = ClientSecretTextBox.Text; try { StoreParameters(); SalesForceAuthorizationHelper authorizationHelper = new SalesForceAuthorizationHelper(Credentials.ClientId, Credentials.ClientSecret, RedirectUrl); string authorizationUrl = authorizationHelper.GetAuthorizationUrl(ParametersId); Response.Redirect(authorizationUrl, false); } catch (Exception exception) { HandleError(exception); } } } #endregion #region "Private methods" private string GetOrganizationName(OrganizationCredentials credentials, string organizationId) { RefreshTokenSessionProvider provider = new RefreshTokenSessionProvider { ClientId = credentials.ClientId, ClientSecret = credentials.ClientSecret, RefreshToken = credentials.RefreshToken }; Session session = provider.CreateSession(); SalesForceClient client = new SalesForceClient(session); EntityModel organizationModel = client.DescribeEntity("Organization"); SelectEntitiesResult result = client.SelectEntities(String.Format("select Name, Division from Organization where Id = '{0}'", organizationId), organizationModel); if (result.TotalEntityCount == 0) { return String.Empty; } Entity organization = result.Entities[0]; string name = organization.GetAttributeValue("Name"); string division = organization.GetAttributeValue("Division"); StringBuilder builder = new StringBuilder(); if (!String.IsNullOrEmpty(name)) { builder.Append(name); } if (!String.IsNullOrEmpty(division)) { if (builder.Length > 0) { builder.AppendFormat("({0})", division); } else { builder.Append(division); } } return builder.ToString(); } private void StoreParameters() { Hashtable parameters = WindowHelper.GetItem(ParametersId) as Hashtable; parameters["Credentials"] = EncryptionHelper.EncryptData(OrganizationCredentials.Serialize(Credentials)); WindowHelper.Add(ParametersId, parameters); } private void RestoreParameters() { string parametersId = QueryHelper.GetString("pid", null); if (!String.IsNullOrEmpty(parametersId)) { if (!QueryHelper.ValidateHash("hash")) { throw new Exception("[SalesForceAuthorizationSetupPage.RestoreParameters]: Invalid query hash."); } } else { parametersId = QueryHelper.GetString("state", null); } Hashtable parameters = WindowHelper.GetItem(parametersId) as Hashtable; if (parameters == null) { throw new Exception("[SalesForceAuthorizationSetupPage.RestoreParameters]: The dialog page parameters are missing, the session might have been lost."); } string credentials = ValidationHelper.GetString(parameters["Credentials"], String.Empty); if (!String.IsNullOrEmpty(credentials)) { mCredentials = OrganizationCredentials.Deserialize(EncryptionHelper.DecryptData(credentials).TrimEnd('\0')); } else { mCredentials = new OrganizationCredentials(); } mSourceMessageLabelClientId = ValidationHelper.GetString(parameters["MessageLabelClientId"], String.Empty); mSourceCredentialsHiddenFieldClientId = ValidationHelper.GetString(parameters["CredentialsHiddenFieldClientId"], String.Empty); mSourceUrlScheme = ValidationHelper.GetString(parameters["UrlScheme"], String.Empty); mSourceUrlPort = ValidationHelper.GetInteger(parameters["UrlPort"], -1); mSourceSiteName = ValidationHelper.GetString(parameters["SiteName"], String.Empty); } private void RedirectToScheme(string scheme, int port) { Uri currentUrl = URLHelper.Url; UriBuilder builder = new UriBuilder { Scheme = scheme, Port = port, Host = currentUrl.Host, Path = currentUrl.AbsolutePath, Query = String.Format("state={0}", ParametersId) }; Response.Redirect(builder.ToString(), false); } private void CloseDialog(string message) { string html = HTMLHelper.HTMLEncode(message); CredentialsHiddenField.Value = EncryptionHelper.EncryptData(OrganizationCredentials.Serialize(Credentials)); MessageHiddenField.Value = html; MessageLabel.InnerHtml = html; MessageLabel.Visible = true; MainMessagePanel.Visible = true; MainPanel.Visible = false; FooterPanel.Visible = false; } private void HandleError(Exception exception) { SalesForceError.Report(exception); EventLogProvider.LogException("Salesforce.com Connector", "AuthorizationSetupPage", exception); } #endregion }