using System; using System.Collections.Generic; using System.Text; using System.Web; using System.Web.Security; using CMS.CMSHelper; using CMS.GlobalHelper; using CMS.MembershipProvider; using CMS.PortalControls; using CMS.PortalEngine; using CMS.SettingsProvider; using CMS.SiteProvider; using CMS.DocumentEngine; using CMS.WebAnalytics; public partial class CMSWebParts_Membership_OpenID_OpenIDLogon : CMSAbstractWebPart { #region "Variables" private CMSOpenIDHelper openIDhelper = null; #endregion #region "Constants" protected const string PROVIDERS_LOCATION = "~/CMSWebparts/Membership/OpenID/OpenID_files/"; protected const string USERNAME_MACRO = "##username##"; protected const string SESSION_NAME_USERDATA = "OpenIDAuthenticatedUserData"; protected const string SESSION_NAME_URL = "OpenIDProviderURL"; #endregion #region "Public properties" /// /// Gets or sets OpenID providers used for login. /// public string Providers { get { return ValidationHelper.GetString(GetValue("Providers"), ""); } set { SetValue("Providers", value); } } /// /// Gets or sets the value that indicates whether to show sign out link. /// public bool ShowSignOut { get { return ValidationHelper.GetBoolean(GetValue("ShowSignOut"), true); } set { SetValue("ShowSignOut", value); } } /// /// Gets or sets the value that buttons will be used instead of links. /// public bool ShowAsButton { get { return ValidationHelper.GetBoolean(GetValue("ShowAsButton"), false); } set { SetValue("ShowAsButton", value); } } /// /// Gets or sets sign in button image URL. /// public string SignInImageURL { get { return DataHelper.GetNotEmpty(GetValue("SignInImageURL"), GetImageUrl(PROVIDERS_LOCATION + "signin.gif")); } set { SetValue("SignInImageURL", value); } } /// /// Gets or sets sign out button image URL. /// public string SignOutImageURL { get { return DataHelper.GetNotEmpty(GetValue("SignOutImageURL"), GetImageUrl(PROVIDERS_LOCATION + "signout.gif")); } set { SetValue("SignOutImageURL", value); } } /// /// Gets or sets sign in text. /// public string SignInText { get { return ValidationHelper.GetString(GetValue("SignInText"), ""); } set { SetValue("SignInText", value); } } /// /// Gets or sets sign out text. /// public string SignOutText { get { return ValidationHelper.GetString(GetValue("SignOutText"), ""); } set { SetValue("SignOutText", value); } } /// /// Indicates if BirthDate should be requested in registration process. /// public string BirthDateRequest { get { return ValidationHelper.GetString(GetValue("BirthDate"), ""); } set { SetValue("BirthDate", value); } } /// /// The level of interest a relying party has in the Country of the user. /// public string CountryRequest { get { return ValidationHelper.GetString(GetValue("Country"), ""); } set { SetValue("Country", value); } } /// /// The level of interest a relying party has in the email of the user. /// public string EmailRequest { get { return ValidationHelper.GetString(GetValue("Email"), ""); } set { SetValue("Email", value); } } /// /// The level of interest a relying party has in the full name of the user. /// public string FullNameRequest { get { return ValidationHelper.GetString(GetValue("FullName"), ""); } set { SetValue("FullName", value); } } /// /// The level of interest a relying party has in the gender of the user. /// public string GenderRequest { get { return ValidationHelper.GetString(GetValue("Gender"), ""); } set { SetValue("Gender", value); } } /// /// The level of interest a relying party has in the language of the user. /// public string LanguageRequest { get { return ValidationHelper.GetString(GetValue("Language"), ""); } set { SetValue("Language", value); } } /// /// The level of interest a relying party has in the nickname of the user. /// public string NicknameRequest { get { return ValidationHelper.GetString(GetValue("Nickname"), ""); } set { SetValue("Nickname", value); } } /// /// The level of interest a relying party has in the postal code of the user. /// public string PostalCodeRequest { get { return ValidationHelper.GetString(GetValue("PostalCode"), ""); } set { SetValue("PostalCode", value); } } /// /// The level of interest a relying party has in the time zone of the user. /// public string TimeZoneRequest { get { return ValidationHelper.GetString(GetValue("TimeZone"), ""); } set { SetValue("TimeZone", value); } } /// /// Gets or sets the value indicating if textbox should be displayed. /// public bool DisplayTextbox { get { return ValidationHelper.GetBoolean(GetValue("DisplayTextbox"), true); } set { SetValue("DisplayTextbox", value); } } /// /// Gets or sets the conversion track name used after successful registration. /// public string TrackConversionName { get { return ValidationHelper.GetString(GetValue("TrackConversionName"), ""); } set { if ((value != null) && (value.Length > 400)) { value = value.Substring(0, 400); } SetValue("TrackConversionName", value); } } /// /// Gets or sets the conversion value used after successful registration. /// public double ConversionValue { get { return ValidationHelper.GetDoubleSystem(GetValue("ConversionValue"), 0); } set { SetValue("ConversionValue", value); } } /// /// Gets or sets the value that indicates whether after successful registration is /// notification email sent to the administrator /// public bool NotifyAdministrator { get { return ValidationHelper.GetBoolean(GetValue("NotifyAdministrator"), false); } set { SetValue("NotifyAdministrator", value); } } /// /// Gets the sender email (from). /// private string FromAddress { get { return SettingsKeyProvider.GetStringValue(CMSContext.CurrentSiteName + ".CMSNoreplyEmailAddress"); } } /// /// Gets the recipient email (to). /// private string ToAddress { get { return SettingsKeyProvider.GetStringValue(CMSContext.CurrentSiteName + ".CMSAdminEmailAddress"); } } #endregion #region "Methods" /// /// Content loaded event handler. /// public override void OnContentLoaded() { base.OnContentLoaded(); SetupControl(); } /// /// Reloads data. /// public override void ReloadData() { base.ReloadData(); SetupControl(); } /// /// Initializes the control properties. /// protected void SetupControl() { if (StopProcessing) { Visible = false; } else { // Check renamed DLL library if (CMSOpenIDHelper.CheckOpenIdDLL()) { // Check if OpenID module is enabled if (SettingsKeyProvider.GetBoolValue(CMSContext.CurrentSiteName + ".CMSEnableOpenID")) { ltlScript.Text = ScriptHelper.GetIncludeScript(PROVIDERS_LOCATION + "OpenIDSelector.js"); lblError.Text = GetString("openid.invalidid"); SetProviders(); DisplayButtons(); openIDhelper = new CMSOpenIDHelper(); CheckStatus(); } else { // Error label is displayed in Design mode when OpenID is disabled if (CMSContext.ViewMode == ViewModeEnum.Design) { StringBuilder parameter = new StringBuilder(); parameter.Append(GetString("header.sitemanager") + " -> "); parameter.Append(GetString("settingscategory.cmssettings") + " -> "); parameter.Append(GetString("settingscategory.cmsmembership") + " -> "); parameter.Append(GetString("settingscategory.cmsmembershipauthentication") + " -> "); parameter.Append(GetString("settingscategory.cmsopenid")); if (CMSContext.CurrentUser.UserSiteManagerAdmin) { // Make it link for SiteManager Admin parameter.Insert(0, ""); parameter.Append(""); } lblError.Text = String.Format(GetString("mem.openid.disabled"), parameter.ToString()); lblError.Visible = true; txtInput.Visible = false; } else { Visible = false; } } } // Error label is displayed in Design mode when OpenID library is not enabled else { lblError.Text = ResHelper.GetString("mem.openid.library"); lblError.Visible = true; txtInput.Visible = false; } } } /// /// Prepares script with user-defined providers. /// protected void SetProviders() { // Set default value for providers string providers = null; if (!String.IsNullOrEmpty(Providers)) { // Split providers by rows string[] rows = Providers.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); // Create javascript variable providers = "var providers = ["; int i = 1; string[] parts = null; string part0 = null; string part1 = null; string url_prefix = null; string url_suffix = null; string[] urlParts = null; bool customusername = false; foreach (string row in rows) { string rowValue = row.Trim(); if (i != 1) { providers += ", "; } providers += "{"; parts = rowValue.Split(new char[] { '|' }); part0 = string.Empty; part1 = string.Empty; // Check if providers are filled in correctly if (parts.Length >= 2) { part0 = parts[0]; part1 = parts[1]; } // Split URL to get suffix and prefix url_prefix = null; url_suffix = part1; customusername = false; // Check if URL contains macro for custom username if (part1.ToLowerCSafe().Contains(USERNAME_MACRO.ToLowerCSafe())) { urlParts = part1.Split(new string[] { USERNAME_MACRO }, StringSplitOptions.None); url_prefix = urlParts[0]; url_suffix = urlParts[1]; customusername = true; } // long name + short name providers += " longname: \"" + part0 + "\", shortname: \"" + part0 + "\","; // url prefix providers += " url_prefix: \"" + url_prefix + "\","; // url suffix providers += " url_suffix: \"" + url_suffix + "\","; // usercalled (blog name, user name, user id) which will be displayed before username textbox providers += " usercalled: \"username\","; // website url providers += " website: \"" + url_suffix + "\","; // icon if ((parts.Length > 2) && !String.IsNullOrEmpty(parts[2])) { providers += " icon: \"" + URLHelper.GetAbsoluteUrl(PROVIDERS_LOCATION + parts[2].ToLowerCSafe()) + "\","; } else { providers += " icon: \"" + URLHelper.GetAbsoluteUrl(PROVIDERS_LOCATION + "openid.png") + "\","; } // id (used to determine cookie) providers += " id: " + i + ","; // enable username input (openid1 = FALSE means no username input) providers += " openid1: " + customusername.ToString().ToLowerCSafe() + ","; // openid2 providers += " openid2: true"; providers += " }"; i++; } providers += "];"; } providers += "\n"; providers += "var iconlocation = \"" + URLHelper.GetAbsoluteUrl(GetImageUrl("CMSModules/CMS_OpenID/")) + "\"; \n"; providers += "var providerlocation = \"" + URLHelper.GetAbsoluteUrl(PROVIDERS_LOCATION) + "\";\n"; if (DisplayTextbox) { providers += "var idselector_input_id = \"" + txtInput.ClientID + "\";\n"; } else { providers += "var idselector_input_id = \"" + hdnValue.ClientID + "\";\n"; } providers += "var displaytextbox = " + DisplayTextbox.ToString().ToLowerCSafe() + ";\n"; providers += "var otheropenid = \"" + GetString("mem.openid.other") + "\";\n"; providers += "var clicktosignin = \"" + GetString("mem.openid.click") + "\";\n"; ltlProvidersVariables.Text = ScriptHelper.GetScript(providers); } /// /// Displays buttons depending on web part settings. /// protected void DisplayButtons() { // If user is already authenticated if (CMSContext.CurrentUser.IsAuthenticated()) { if (ShowSignOut) { // If text is set use text/button link if (!string.IsNullOrEmpty(SignOutText)) { // Button link if (ShowAsButton) { pnlLogon.DefaultButton = btnSignOut.ID; btnSignOut.Text = SignOutText; btnSignOut.Visible = true; } // Text link else { pnlLogon.DefaultButton = btnSignOutLink.ID; btnSignOutLink.Text = SignOutText; btnSignOutLink.Visible = true; } } // Image link else { pnlLogon.DefaultButton = btnSignOutImage.ID; btnSignOutImage.ImageUrl = ResolveUrl(SignOutImageURL); btnSignOutImage.Visible = true; btnSignOutImage.ToolTip = GetString("webparts_membership_signoutbutton.signout"); btnSignOut.Text = GetString("webparts_membership_signoutbutton.signout"); } } txtInput.Visible = false; ltlScript.Visible = false; ltlProvidersVariables.Visible = false; } else { // If text is set use text/button link if (!string.IsNullOrEmpty(SignInText)) { // Button link if (ShowAsButton) { pnlLogon.DefaultButton = btnSignIn.ID; btnSignIn.Text = SignInText; btnSignIn.Visible = true; } // Text link else { pnlLogon.DefaultButton = btnSignInLink.ID; btnSignInLink.Text = SignInText; btnSignInLink.Visible = true; } } // Image link else { pnlLogon.DefaultButton = btnSignInImage.ID; btnSignInImage.ImageUrl = ResolveUrl(SignInImageURL); btnSignInImage.Visible = true; btnSignInImage.ToolTip = GetString("webparts_membership_signoutbutton.signin"); btnSignIn.Text = GetString("webparts_membership_signoutbutton.signin"); } txtInput.Visible = true; ltlScript.Visible = true; ltlProvidersVariables.Visible = true; } // Hide textbox when applicable if (!DisplayTextbox) { txtInput.Visible = false; } } /// /// Checks status of current user. /// protected void CheckStatus() { // Get current site name string siteName = CMSContext.CurrentSiteName; string error = null; // Check return URL string returnUrl = QueryHelper.GetString("returnurl", null); returnUrl = HttpUtility.UrlDecode(returnUrl); // Get current URL string currentUrl = URLHelper.CurrentURL; currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "token"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.ns"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.mode"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.return_to"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.claimed_id"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.identity"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.assoc_handle"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.realm"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.response_nonce"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.signed"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.op_endpoint"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.pape.auth_level.nist"); currentUrl = URLHelper.RemoveParameterFromUrl(currentUrl, "openid.sig"); // Get OpenID response status switch (openIDhelper.CheckStatus()) { // User is authenticated case CMSOpenIDHelper.RESPONSE_AUTHENTICATED: // Claimed ID not found = save new user if (OpenIDUserInfoProvider.GetUserInfoByOpenID(openIDhelper.ClaimedIdentifier) == null) { // Check whether additional user info page is set string additionalInfoPage = SettingsKeyProvider.GetStringValue(siteName + ".CMSRequiredOpenIDPage").Trim(); // No page set, user can be created if (String.IsNullOrEmpty(additionalInfoPage)) { // Register new user UserInfo ui = AuthenticationHelper.AuthenticateOpenIDUser(openIDhelper.ClaimedIdentifier, ValidationHelper.GetString(SessionHelper.GetValue(SESSION_NAME_URL), null), siteName, false, true, ref error); // If user was found or successfuly created if (ui != null) { // Load values submited by OpenID provider // Load date of birth if (openIDhelper.BirthDate != DateTime.MinValue) { ui.UserSettings.UserDateOfBirth = openIDhelper.BirthDate; } // Load default country if (openIDhelper.Culture != null) { ui.PreferredCultureCode = openIDhelper.Culture.Name; } // Load e-mail if (!String.IsNullOrEmpty(openIDhelper.Email)) { ui.Email = openIDhelper.Email; } // Nick name if (!String.IsNullOrEmpty(openIDhelper.Nickname)) { ui.UserSettings.UserNickName = openIDhelper.Nickname; } // User gender if (openIDhelper.UserGender != null) { ui.UserSettings.UserGender = (int)openIDhelper.UserGender; } UserInfoProvider.SetUserInfo(ui); // If user is enabled if (ui.Enabled) { // Create autentification cookie AuthenticationHelper.SetAuthCookieWithUserData(ui.UserName, true, Session.Timeout, new string[] { "openidlogin" }); // Log activity Activity activityLogin = new ActivityUserLogin(ModuleCommands.OnlineMarketingGetUserLoginContactID(ui), ui, CMSContext.CurrentDocument, CMSContext.ActivityEnvironmentVariables); activityLogin.Log(); } // Send registration e-mails // E-mail confirmation is not required as user already provided confirmation by successful login using OpenID AuthenticationHelper.SendRegistrationEmails(ui, null, null, false, false); // Notify administrator if (NotifyAdministrator && !String.IsNullOrEmpty(FromAddress) && !String.IsNullOrEmpty(ToAddress)) { AuthenticationHelper.NotifyAdministrator(ui, FromAddress, ToAddress); } // Track user registration AuthenticationHelper.TrackUserRegistration(TrackConversionName, ConversionValue, siteName, ui); Activity activity = new ActivityRegistration(ui, CMSContext.CurrentDocument, CMSContext.ActivityEnvironmentVariables); if (activity.Data != null) { activity.Data.ContactID = ModuleCommands.OnlineMarketingGetUserLoginContactID(ui); activity.Log(); } } // Redirect when authentication was succesfull if (String.IsNullOrEmpty(error)) { if (!String.IsNullOrEmpty(returnUrl)) { URLHelper.Redirect(URLHelper.GetAbsoluteUrl(returnUrl)); } else { URLHelper.Redirect(currentUrl); } } // Display error otherwise else { lblError.Text = error; lblError.Visible = true; } } // Additional information page is set else { // Store user object in session for additional use StoreResponseInSession(); // Redirect to additional info page string targetURL = URLHelper.GetAbsoluteUrl(additionalInfoPage); if (!String.IsNullOrEmpty(returnUrl)) { // Add return URL to parameter targetURL = URLHelper.AddParameterToUrl(targetURL, "returnurl", HttpUtility.UrlEncode(returnUrl)); } URLHelper.Redirect(targetURL); } } // Claimed OpenID is in DB else { // Login existing user UserInfo ui = AuthenticationHelper.AuthenticateOpenIDUser(openIDhelper.ClaimedIdentifier, ValidationHelper.GetString(SessionHelper.GetValue(SESSION_NAME_URL), null), siteName, false, true, ref error); if ((ui != null) && (ui.Enabled)) { // Create autentification cookie AuthenticationHelper.SetAuthCookieWithUserData(ui.UserName, true, Session.Timeout, new string[] { "openilogin" }); // Log activity int contactID = ModuleCommands.OnlineMarketingGetUserLoginContactID(ui); Activity activityLogin = new ActivityUserLogin(contactID, ui, CMSContext.CurrentDocument, CMSContext.ActivityEnvironmentVariables); activityLogin.Log(); // Redirect user if (!String.IsNullOrEmpty(returnUrl)) { URLHelper.Redirect(URLHelper.GetAbsoluteUrl(returnUrl)); } else { URLHelper.Redirect(currentUrl); } } // Display error which occured during authentication process else if (!String.IsNullOrEmpty(error)) { lblError.Text = error; lblError.Visible = true; } // Otherwise is user disabled else { lblError.Text = GetString("membership.userdisabled"); lblError.Visible = true; } } break; // Authentication was canceled case CMSOpenIDHelper.RESPONSE_CANCELED: lblError.Text = GetString("openid.logincanceled"); lblError.Visible = true; break; // Authentication failed case CMSOpenIDHelper.RESPONSE_FAILED: lblError.Text = GetString("openid.loginfailed"); lblError.Visible = true; break; } } /// /// Stores data from OpenID response in session. /// private void StoreResponseInSession() { Dictionary response = new Dictionary(); response["BirthDate"] = openIDhelper.BirthDate; response["ClaimedIdentifier"] = openIDhelper.ClaimedIdentifier; response["Country"] = openIDhelper.Country; response["Culture"] = openIDhelper.Culture; response["Email"] = openIDhelper.Email; response["FullName"] = openIDhelper.FullName; response["Language"] = openIDhelper.Language; response["Nickname"] = openIDhelper.Nickname; response["PostalCode"] = openIDhelper.PostalCode; response["TimeZone"] = openIDhelper.TimeZone; response["UserGender"] = openIDhelper.UserGender; SessionHelper.SetValue(SESSION_NAME_USERDATA, response); } #endregion #region "Events" /// /// Sign In clicked event handler. /// protected void btnSignIn_Click(object sender, EventArgs e) { openIDhelper = new CMSOpenIDHelper(); string openidURL = null; if (DisplayTextbox) { openidURL = txtInput.Text.Trim(); } else { openidURL = hdnValue.Value; } // Check if validation was successful if (CMSOpenIDHelper.IsValid(openidURL)) { // Store ProviderURL for later use SessionHelper.SetValue(SESSION_NAME_URL, openidURL); // Send request string response = openIDhelper.SendRequest(openidURL, BirthDateRequest, CountryRequest, EmailRequest, FullNameRequest, GenderRequest, LanguageRequest, NicknameRequest, PostalCodeRequest, TimeZoneRequest); if (!String.IsNullOrEmpty(response)) { lblError.Visible = true; lblError.Text = response; } } else { if (DisplayTextbox) { lblError.Text = GetString("mem.openid.enterproviderurl"); } else { lblError.Text = GetString("mem.openid.selectprovider"); } lblError.Visible = true; } } /// /// Sign out button clicked. /// protected void btnSignOut_Click(object sender, EventArgs e) { if (CMSContext.CurrentUser.IsAuthenticated()) { // Sign out from CMS CMSContext.LogoutUser(); CMSContext.CurrentUser = null; Response.Cache.SetNoStore(); // Clear used session SessionHelper.Remove(SESSION_NAME_URL); SessionHelper.Remove(SESSION_NAME_USERDATA); // Redirect to return URL string returnUrl = QueryHelper.GetString("returnurl", URLHelper.CurrentURL); URLHelper.Redirect(URLHelper.GetAbsoluteUrl(HttpUtility.UrlDecode(returnUrl))); } } #endregion }