private async Task GetTokenAsync3(string code) { var d = new Dictionary <string, string>(); d.Add("grant_type", "authorization_code"); d.Add("client_id", "ownerapi"); d.Add("code", code); d.Add("code_verifier", code_verifier); d.Add("redirect_uri", authHost + "/void/callback"); string json = new JavaScriptSerializer().Serialize(d); string tmpAccessToken; using (HttpClient client = new TessHttpClient(new TessClientHandler(null, null))) { client.DefaultRequestHeaders.Referrer = referrer; using (StringContent content = new StringContent(json, Encoding.UTF8, "application/json")) { HttpResponseMessage result = await client.PostAsync(authHost + "/oauth2/v3/token", content); if (result.StatusCode != HttpStatusCode.OK) { throw new Exception("authorization_code - Error: " + result.StatusCode); } string resultContent = result.Content.ReadAsStringAsync().Result; dynamic jsonResult = new JavaScriptSerializer().DeserializeObject(resultContent); //RefreshToken = jsonResult["refresh_token"]; tmpAccessToken = jsonResult["access_token"]; } } await GetTokenAsync4Async(tmpAccessToken); }
private string MFA2(string MFA_Code, string factor_id) { using (HttpClient client = new TessHttpClient(new TessClientHandler(false, false))) { client.DefaultRequestHeaders.Add("Cookie", cookie); Dictionary <string, string> d = new Dictionary <string, string>(); d.Add("factor_id", factor_id); d.Add("passcode", MFA_Code); d.Add("transaction_id", transaction_id); string json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(d); using (var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json")) { HttpResponseMessage result = client.PostAsync(authHost + "/oauth2/v3/authorize/mfa/verify", content).Result; string resultContent = result.Content.ReadAsStringAsync().Result; try { dynamic jsonResult = new JavaScriptSerializer().DeserializeObject(resultContent); object o = jsonResult["data"]["valid"]; if ((bool)o) { return(MFA3()); } } catch (Exception ex) { Log.Error("Error: MFA2 : " + resultContent, ex); } } } return("NULL"); }
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)); } }
private string MFA3() { using (HttpClient client = new TessHttpClient(new TessClientHandler(false, false))) { client.DefaultRequestHeaders.Add("Cookie", cookie); Dictionary <string, string> d = new Dictionary <string, string>(); d.Add("transaction_id", transaction_id); using (FormUrlEncodedContent content = new FormUrlEncodedContent(d)) { UriBuilder b = new UriBuilder(authHost + "/oauth2/v3/authorize"); b.Port = -1; var q = HttpUtility.ParseQueryString(b.Query); q.Add("client_id", "ownerapi"); q.Add("code_challenge", code_challenge); q.Add("code_challenge_method", "S256"); q.Add("redirect_uri", authHost + "/void/callback"); q.Add("response_type", "code"); q.Add("scope", "openid email offline_access"); q.Add("state", state); b.Query = q.ToString(); string url = b.ToString(); var temp = content.ReadAsStringAsync().Result; HttpResponseMessage result = client.PostAsync(url, content).Result; string resultContent = result.Content.ReadAsStringAsync().Result; Uri location = result.Headers.Location; if (result.StatusCode == HttpStatusCode.Redirect && location != null) { string code = HttpUtility.ParseQueryString(location.Query).Get("code"); Log.Debug("Code: " + code); return(code); } else { Log.Warning("Error: MFA2 Fail!"); return("NULL"); } } } }
private async Task GetTokenAsync4Async(string tmpAccessToken) { var d = new Dictionary <string, string>(); d.Add("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"); d.Add("client_id", TESLA_CLIENT_ID); d.Add("client_secret", TESLA_CLIENT_SECRET); string json = new JavaScriptSerializer().Serialize(d); using (HttpClient client = new TessHttpClient(new TessClientHandler(null, null))) { client.Timeout = TimeSpan.FromSeconds(5); client.DefaultRequestHeaders.Add("Authorization", "Bearer " + tmpAccessToken); using (var content = new StringContent(json, Encoding.UTF8, "application/json")) { HttpResponseMessage result = await client.PostAsync("https://owner-api.teslamotors.com/oauth/token", content); string resultContent = result.Content.ReadAsStringAsync().Result; Log.Debug("HttpStatus: " + result.StatusCode.ToString()); LoginResponse = SerializeTool.DeSerializeJson <LoginResponse>(resultContent); } } }
/// <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)); }
private async Task <bool> GetTokenAsync2(MatchCollection mc, string user, string pw) { int length = 0; Dictionary <string, string> d = new Dictionary <string, string>(); foreach (Match m in mc) { string key = m.Groups[1].Value; string value = m.Groups[2].Value; if (d.ContainsKey(key)) { continue; } if (key.Contains("cancel")) { continue; } d.Add(key, value); if (key == "transaction_id") { transaction_id = value; } length += m.Groups[1].Value.Length; length += m.Groups[2].Value.Length; length += 4; } d.Add("identity", user); d.Add("credential", pw); string code = ""; using (HttpClient client = new TessHttpClient(new TessClientHandler(false, false))) { client.DefaultRequestHeaders.Add("Cookie", cookie); using (FormUrlEncodedContent content = new FormUrlEncodedContent(d)) { UriBuilder b = new UriBuilder(authHost + "/oauth2/v3/authorize"); b.Port = -1; var q = HttpUtility.ParseQueryString(b.Query); q["client_id"] = "ownerapi"; q["code_challenge"] = code_challenge; q["code_challenge_method"] = "S256"; q["redirect_uri"] = authHost + "/void/callback"; q["response_type"] = "code"; q["scope"] = "openid email offline_access"; q["state"] = state; b.Query = q.ToString(); string url = b.ToString(); referrer = b.Uri; var temp = content.ReadAsStringAsync().Result; HttpResponseMessage result = await client.PostAsync(url, content); string resultContent = result.Content.ReadAsStringAsync().Result; Uri location = result.Headers.Location; if (result.StatusCode != HttpStatusCode.Redirect) { if (result.StatusCode == HttpStatusCode.OK && resultContent.Contains("passcode")) { return(false); // Signalisieren das wir mit MFA weiter machen müssen } else { Log.Error("GetTokenAsync2 HttpStatus: " + result.StatusCode.ToString() + " / Expecting: Redirect !!!"); throw new Exception("GetToken: " + result.StatusCode); } } // Ohne MFA if (location == null) { throw new Exception("GetTokenAsync2 Redirect Location = null!!! Wrong credentials?"); } if (result.StatusCode == HttpStatusCode.Redirect && (location != null)) { code = HttpUtility.ParseQueryString(location.Query).Get("code"); await GetTokenAsync3(code); return(true); } else { throw new Exception("GetTokenAsync2 - result.StatusCode: " + result.StatusCode); } } } }