private string MFA1(string MFA_Code) { string resultContent; using (HttpClient client = new TessHttpClient(new TessClientHandler(null, false))) { client.DefaultRequestHeaders.Add("Cookie", cookie); UriBuilder b = new UriBuilder(authHost + "/oauth2/v3/authorize/mfa/factors"); b.Port = -1; var q = HttpUtility.ParseQueryString(b.Query); q.Add("transaction_id", transaction_id); b.Query = q.ToString(); string url = b.ToString(); HttpResponseMessage result = client.GetAsync(url).Result; resultContent = result.Content.ReadAsStringAsync().Result; Log.Debug("MFA1 Result: " + resultContent); dynamic jsonResult = new JavaScriptSerializer().DeserializeObject(resultContent); string factor_id = null; try { factor_id = jsonResult["data"][0]["id"]; } catch (Exception ex) { Log.Error("MFA1 ResultContent: " + resultContent, ex); } return(MFA2(MFA_Code, factor_id)); } }
/// <summary> /// Does the login. /// </summary> /// <param name="user">The user.</param> /// <param name="pw">The password.</param> /// <returns>true: login OK / finished; false: MFA needed!</returns> public async Task <bool> DoLogin(string user, string pw) { MatchCollection m; if (String.IsNullOrEmpty(user) || String.IsNullOrEmpty(pw)) { throw new Exception("NO Credentials"); } code_verifier = RandomString(86); code_challenge_SHA256 = ComputeSHA256Hash(code_verifier); code_challenge = Convert.ToBase64String(Encoding.Default.GetBytes(code_challenge_SHA256)); state = RandomString(20); using (TessHttpClient client = new TessHttpClient(new TessClientHandler(false, null))) { client.Timeout = TimeSpan.FromSeconds(30); Dictionary <string, string> values = new Dictionary <string, string> { { "client_id", "ownerapi" }, { "code_challenge", code_challenge }, { "code_challenge_method", "S256" }, { "redirect_uri", authHost + "/void/callback" }, { "response_type", "code" }, { "scope", "openid email offline_access" }, { "state", state }, { "login_hint", "" } }; string json = new JavaScriptSerializer().Serialize(values); using (StringContent content = new StringContent(json.ToString(), Encoding.UTF8, "application/json")) { UriBuilder b = new UriBuilder(authHost + "/oauth2/v3/authorize"); b.Port = -1; var q = HttpUtility.ParseQueryString(b.Query); foreach (var v in values) { q[v.Key] = v.Value; } b.Query = q.ToString(); string url = b.ToString(); HttpResponseMessage result = await client.GetAsync(url); string resultContent = result.Content.ReadAsStringAsync().Result; m = Regex.Matches(resultContent, "type=\\\"hidden\\\" name=\\\"(.*?)\\\" value=\\\"(.*?)\\\""); IEnumerable <string> cookies = result.Headers.SingleOrDefault(header => header.Key == "Set-Cookie").Value; cookie = cookies.ToList()[0]; cookie = cookie.Substring(0, cookie.IndexOf(" ")); cookie = cookie.Trim(); if (resultContent.Contains("authorization_required")) { throw new Exception("Wrong Credentials"); } if (result.StatusCode == HttpStatusCode.RedirectMethod) { if (result.Headers.Location.Host == "auth.tesla.cn" && authHost != "https://auth.tesla.cn") { authHost = "https://auth.tesla.cn"; Log.Info("Use chinese auth server: auth.tesla.cn!"); return(await DoLogin(user, pw)); } } } } return(await GetTokenAsync2(m, user, pw)); }