using System; using System.Web.UI; using System.Web; using System.Data; using System.Text.RegularExpressions; using CMS.CMSHelper; using CMS.GlobalHelper; using CMS.LicenseProvider; using CMS.MembershipProvider; using CMS.PortalEngine; using CMS.SettingsProvider; using CMS.SiteProvider; using CMS.DocumentEngine; using CMS.UIControls; using CMS.WebAnalytics; using CMS.ExtendedControls; /// /// This page handles the login, logout and clearcookie Web Auth /// actions. When you create a Windows Live application, you must /// specify the URL of this handler page. /// public partial class CMSPages_LiveIDLogin : CMSPage { #region "Private fields" private static string defaultPage = URLHelper.ResolveUrl("~/Default.aspx"); private static string loginPage = SettingsKeyProvider.GetStringValue(CMSContext.CurrentSiteName + ".CMSSecuredAreasLogonPage"); private static string logoutPage = defaultPage; private const string liveCookieName = "webauthtoken"; private String siteName = String.Empty; private String relativeURL = String.Empty; private String conversionName = String.Empty; private String conversionValue = String.Empty; #endregion #region "Methods" /// /// Parse parameters from session /// /// LiveID login parameters private void ParseParameters(String[] parameters) { if ((parameters != null) && (parameters.Length == 3)) { relativeURL = HttpUtility.UrlDecode(parameters[0]); conversionName = HttpUtility.UrlDecode(parameters[1]); conversionValue = HttpUtility.UrlDecode(parameters[2]); } } /// /// Get user information and logs user (register if no user found) /// private void ProcessLiveIDLogin() { // Get authorization code from URL String code = QueryHelper.GetString("code", String.Empty); // Additional info page for login string additionalInfoPage = SettingsKeyProvider.GetStringValue(siteName + ".CMSLiveIDRequiredUserDataPage"); // Create windows login object WindowsLiveLogin wwl = new WindowsLiveLogin(siteName); // Windows live User WindowsLiveLogin.User liveUser = null; if (!WindowsLiveLogin.UseServerSideAuthorization) { if (!RequestHelper.IsPostBack()) { // If client authentication, get token displayed in url after # from window.location String script = ControlsHelper.GetPostBackEventReference(this, "#").Replace("'#'", "window.location"); ScriptHelper.RegisterClientScriptBlock(this, typeof(string), "PostbackScript", ScriptHelper.GetScript(script)); } else { // Try to get full url from event argument string fullurl = Request["__EVENTARGUMENT"]; // Authentication token - use to get uid String token = ParseToken(fullurl, @"authentication_token=([\w\d.-]+)&"); // User token - this token is used in server auth. scenario. It's stored in user object (for possible further use) so parse it too and store it String accessToken = ParseToken(fullurl, @"access_token=([%\w\d.-]+)&"); if (token != String.Empty) { // Return context from session GetLoginInformation(); // Authenticate user by found token liveUser = wwl.AuthenticateClientToken(token, relativeURL, accessToken); if (liveUser != null) { // Set info to refresh to parent page ScriptHelper.RegisterWOpenerScript(Page); CreateCloseScript(""); } } } } else { GetLoginInformation(); // Process login via Live ID liveUser = wwl.ProcessLogin(code, relativeURL); } // Authorization sucesfull if (liveUser != null) { // Find user by ID UserInfo winUser = UserInfoProvider.GetUserInfoByWindowsLiveID(liveUser.Id); string error = String.Empty; // Register new user if (winUser == null) { // Check whether additional user info page is set // No page set, user can be created/sign if (additionalInfoPage == String.Empty) { // Create new user user UserInfo ui = AuthenticationHelper.AuthenticateWindowsLiveUser(liveUser.Id, siteName, true, ref error); // Remove live user object from session, won't be needed Session.Remove("windowsliveloginuser"); // If user was found or successfuly created if ((ui != null) && (ui.Enabled)) { // Send registration e-mails // E-mail confirmation is not required as user already provided confirmation by successful login using LiveID AuthenticationHelper.SendRegistrationEmails(ui, null, null, false, false); // Track registration into analytics double val = ValidationHelper.GetDouble(CMSContext.CurrentResolver.ResolveMacros(conversionValue), 0); AuthenticationHelper.TrackUserRegistration(conversionName, val, siteName, ui); Activity activity = new ActivityRegistration(ui, CMSContext.CurrentDocument, CMSContext.ActivityEnvironmentVariables); if (activity.Data != null) { activity.Data.ContactID = ModuleCommands.OnlineMarketingGetUserLoginContactID(ui); activity.Log(); } SetAuthCookieAndRedirect(ui); } // User not created else { if (WindowsLiveLogin.UseServerSideAuthorization) { WindowsLiveLogin.ClearCookieAndRedirect(loginPage); } else { CreateCloseScript("clearcookieandredirect"); } } } // Required data page exists else { // Store user object in session for additional info page SessionHelper.SetValue("windowsliveloginuser", liveUser); if (WindowsLiveLogin.UseServerSideAuthorization) { // Redirect to additional info page URLHelper.Redirect(URLHelper.ResolveUrl(additionalInfoPage)); } else { CreateCloseScript("redirectToAdditionalPage"); } } } else { UserInfo ui = AuthenticationHelper.AuthenticateWindowsLiveUser(liveUser.Id, siteName, true, ref error); // If user was found if ((ui != null) && (ui.Enabled)) { SetAuthCookieAndRedirect(ui); } } } } /// /// Parse token from given URL /// /// URL to search /// Regex search pattern private string ParseToken(String url, String pattern) { string token = String.Empty; Regex reg = RegexHelper.GetRegex(pattern); MatchCollection col = reg.Matches(url); if (col.Count > 0) { // Token found token = col[0].Groups[1].ToString(); } return token; } /// /// Creates close script (in ltlSCript) /// /// Script parameter public void CreateCloseScript(String param) { ltlScript.Text = ScriptHelper.GetScript("if (wopener !== 'undefined' && wopener.refreshLiveID != null) {wopener.refreshLiveID('" + param + "');} CloseDialog();"); } /// /// Page load. /// protected void Page_Load(object sender, EventArgs e) { LicenseHelper.CheckFeatureAndRedirect(URLHelper.GetCurrentDomain(), FeatureEnum.WindowsLiveID); siteName = CMSContext.CurrentSiteName; // Sitename must be set if (string.IsNullOrEmpty(siteName)) { return; } ProcessLiveIDLogin(); } /// /// Get login information from session (returnUrl, conversionName, conversionValue) /// private void GetLoginInformation() { // Get login parameters String[] parameters = SessionHelper.GetValue("LiveIDInformtion") as String[]; ParseParameters(parameters); Session.Remove("LiveIDInformtion"); } /// /// Helper method, set authentication cookie and redirect to return URL or default page. /// /// User info /// Windows live user private void SetAuthCookieAndRedirect(UserInfo ui) { // Create autentification cookie AuthenticationHelper.SetAuthCookieWithUserData(ui.UserName, false, Session.Timeout, new string[] { "liveidlogin" }); int contactId = ModuleCommands.OnlineMarketingGetUserLoginContactID(ui); Activity activity = new ActivityUserLogin(contactId, ui, CMSContext.CurrentDocument, CMSContext.ActivityEnvironmentVariables); activity.Log(); // Redirect will be used on parent window if (WindowsLiveLogin.UseServerSideAuthorization) { // If there is some return url redirect there if (!String.IsNullOrEmpty(relativeURL)) { URLHelper.Redirect(ResolveUrl(relativeURL)); } else // Redirect to default page { URLHelper.Redirect(defaultPage); } } } #endregion }