/// <summary> /// Scraps login details. /// </summary> /// <param name="baseUrl">The base URL.</param> /// <param name="browser">The browser.</param> /// <returns></returns> /// <exception cref="System.IO.InvalidDataException">Login form not found or too many forms on the page. /// or /// User name field not found. /// or /// User name field's NAME attribute not specified. /// or /// Password field not found. /// or /// Password field's NAME attribute not specified.</exception> public async Task <ScrapedLoginRequestDetails> ScrapLoginDetails(string baseUrl, IEzBobWebBrowser browser) { var html = await browser.DownloadPageAsyncAsString(baseUrl); HtmlDocument htmlDocument = new HtmlDocument(); htmlDocument.LoadHtml(html); HtmlNodeCollection forms = htmlDocument.DocumentNode.SelectNodes("//form[contains(@action,'login')]"); if (forms == null || forms.Count != 1) { throw new InvalidDataException("Login form not found or too many forms on the page."); } HtmlNode loginForm = forms[0]; string loginUrl = loginForm.Attributes["action"].Value; string loginMethod = loginForm.Attributes.Contains("method") ? loginForm.Attributes["method"].Value : "GET"; HtmlNode userName = loginForm.SelectSingleNode("//input[@id=\"FieldUserID\"]"); if (userName == null) { throw new InvalidDataException("User name field not found."); } if (!userName.Attributes.Contains("name")) { throw new InvalidDataException("User name field's NAME attribute not specified."); } HtmlNode password = loginForm.SelectSingleNode("//input[@id=\"FieldPassword\"]"); if (password == null) { throw new InvalidDataException("Password field not found."); } if (!password.Attributes.Contains("name")) { throw new InvalidDataException("Password field's NAME attribute not specified."); } var loginDetails = new ScrapedLoginRequestDetails { HttpMethod = loginMethod, LoginPageUrl = loginUrl, UserName = userName.Attributes["name"].Value, Password = password.Attributes["name"].Value }; Log.Info(loginDetails.ToString()); return(loginDetails); }
/// <summary> /// Posts the scraped Login. /// </summary> /// <param name="scrapedLoginDetails">The scraped Login details.</param> /// <param name="userName">Name of the user.</param> /// <param name="password">The password.</param> /// <returns></returns> private Task <string> HttpPostLogin(ScrapedLoginRequestDetails scrapedLoginDetails, string userName, string password) { Log.InfoFormat("Logging in as {0}:{1}...", userName, EncryptionUtils.Encrypt(password)); var dictionary = new Dictionary <string, string> { { scrapedLoginDetails.UserName, userName }, { scrapedLoginDetails.Password, password } }; var encodedContent = new FormUrlEncodedContent(dictionary); return(Browser.PostAsyncAndGetStringResponse(baseAddress + scrapedLoginDetails.LoginPageUrl, encodedContent)); }
/// <summary> /// Determines whether we got expected scraped login request details. /// </summary> /// <param name="scrapedLogin">The scraped login request.</param> /// <returns></returns> private bool IsLoginRequestDetailsScrapedAsExpected(ScrapedLoginRequestDetails scrapedLogin) { if (string.IsNullOrEmpty(scrapedLogin.HttpMethod) || string.IsNullOrEmpty(scrapedLogin.LoginPageUrl) || string.IsNullOrEmpty(scrapedLogin.Password) || string.IsNullOrEmpty(scrapedLogin.UserName)) { return(false); } if (!scrapedLogin.HttpMethod.ToUpperInvariant() .Equals("POST")) { Log.Error("Unsupported scrapedLogin method: " + scrapedLogin.HttpMethod); return(false); } return(true); }
/// <summary> /// Logins the specified user name. /// </summary> /// <param name="userName">Name of the user.</param> /// <param name="password">The password.</param> /// <returns></returns> private async Task <InfoAccumulator> Login(string userName, string password) { InfoAccumulator info = new InfoAccumulator(); if (password.Length > maxPasswordLength) { string warning = string.Format("Supplied password ({0}) is too long, truncating to {1} characters.", EncryptionUtils.Encrypt(password), maxPasswordLength); Log.Warn(warning); info.AddWarning(warning); password = password.Substring(0, maxPasswordLength); } try { //Scrap login details ScrapedLoginRequestDetails scrapedLoginDetails = await LoginDetailsScraper.ScrapLoginDetails(baseAddress, Browser); if (!IsLoginRequestDetailsScrapedAsExpected(scrapedLoginDetails)) { info.AddError("login error"); Log.Error("unexpected login page"); return(info); } Log.InfoFormat("Login URL: {0}", scrapedLoginDetails.LoginPageUrl); //try to login string loginResponse = await HttpPostLogin(scrapedLoginDetails, userName, password); if (string.IsNullOrEmpty(loginResponse) || !IsLoginSucceeded(loginResponse, userName)) { return(info); } } catch (Exception ex) { Log.Error(ex); throw; } return(info); }