diff --git a/Source/ProofOfConcept/Program.cs b/Source/ProofOfConcept/Program.cs index c7d1a0e..bab95f4 100644 --- a/Source/ProofOfConcept/Program.cs +++ b/Source/ProofOfConcept/Program.cs @@ -172,7 +172,7 @@ if (app.Environment.IsDevelopment()) }); app.MapGet("/CheckRegisteredApplication", ([FromServices] ITeslaAuthenticatorService service) => service.CheckApplicationRegistrationAsync()); app.MapGet("/RegisterApplication", ([FromServices] ITeslaAuthenticatorService service) => service.RegisterApplicationAsync()); - app.MapGet("/Authorize", async (IHttpContextAccessor contextAccessor) => await (contextAccessor.HttpContext!).ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/Tesla" })); + app.MapGet("/Authorize", async ([FromQuery] string redirect, [FromServices] IHttpContextAccessor contextAccessor) => await (contextAccessor.HttpContext!).ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = redirect })); app.MapGet("/KeyPairing", () => Results.Redirect("https://tesla.com/_ak/automatic-parking.app")); app.MapGet("/Tokens", async (IHttpContextAccessor httpContextAccessor) => { @@ -232,6 +232,45 @@ if (app.Environment.IsDevelopment()) return json; }); + + app.MapGet("/Diagnose", async ([FromServices] ILogger logger, [FromServices] IHttpContextAccessor httpContextAccessor, [FromServices] IHttpClientFactory httpClientFactory) => + { + logger.LogTrace("Checking errors for car..."); + + HttpContext? context = httpContextAccessor.HttpContext; + + if (context is null) + return Results.BadRequest(); + + string? access_token = await context.GetTokenAsync("access_token"); + string? refresh_token = await context.GetTokenAsync("refresh_token"); + logger.LogCritical("User has access_token: {access_token} and refresh_token: {refresh_token}", access_token, refresh_token); + + if (String.IsNullOrEmpty(access_token)) + return Results.LocalRedirect("/Authorize?redirect=Diagnose"); + + HttpClient client = httpClientFactory.CreateClient("InsecureClient"); + client.BaseAddress = new Uri("https://tesla_command_proxy"); + client.DefaultRequestHeaders.Add("Authorization", $"Bearer {access_token}"); + + //Get cars + VehiclesEnvelope? vehiclesEnvelope = await client.GetFromJsonAsync("/api/1/vehicles"); + string[] vinNumbers = vehiclesEnvelope?.Response.Select(x => x.Vin ?? "").Where(v => !String.IsNullOrWhiteSpace(v)).ToArray() ?? Array.Empty(); + logger.LogCritical("User has access to {count} cars: {vins}", vinNumbers.Length, String.Join(", ", vinNumbers)); + + if (vinNumbers.Length == 0) + return Results.Ok("No cars found"); + + foreach (string vinNumber in vinNumbers) + { + HttpResponseMessage responseMessage = await client.GetAsync($"/api/1/vehicles/{vinNumber}/fleet_telemetry_errors"); + string response = await responseMessage.Content.ReadAsStringAsync(); + logger.LogInformation("Telemetry errors for {vinNumber}: {response}", vinNumber, response); + } + + return Results.Ok("Done"); + }); + app.MapGet("/Tesla", async ([FromServices] ILogger logger, [FromServices] IHttpContextAccessor httpContextAccessor, [FromServices] IHttpClientFactory httpClientFactory) => { HttpContext? context = httpContextAccessor.HttpContext; @@ -278,7 +317,7 @@ if (app.Environment.IsDevelopment()) Vins = new List(vinNumbers), Config = new TelemetryConfig() { - Hostname = "tesla-connector.automatic-parking.app", + Hostname = "tesla-telemetry.automatic-parking.app", Port = 443, CertificateAuthority = vm?.CA ?? "EMPTY", Fields = new Dictionary() @@ -298,7 +337,7 @@ if (app.Environment.IsDevelopment()) }); } -app.MapGet("FleetStatus", async (IHttpClientFactory httpClientFactory) => +app.MapGet("/FleetStatus", async (IHttpClientFactory httpClientFactory) => { string access_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InFEc3NoM2FTV0cyT05YTTdLMzFWV0VVRW5BNCJ9.eyJpc3MiOiJodHRwczovL2ZsZWV0LWF1dGgudGVzbGEuY29tL29hdXRoMi92My9udHMiLCJhenAiOiJiMjI0MGVlNC0zMzJhLTQyNTItOTFhYS1iYmNjMjRmNzhmZGIiLCJzdWIiOiJkZDg3Mzc4OC00ZjliLTQyY2UtYmRkNi00YzdmMjQxOGMwN2UiLCJhdWQiOlsiaHR0cHM6Ly9mbGVldC1hcGkucHJkLm5hLnZuLmNsb3VkLnRlc2xhLmNvbSIsImh0dHBzOi8vZmxlZXQtYXBpLnByZC5ldS52bi5jbG91ZC50ZXNsYS5jb20iLCJodHRwczovL2ZsZWV0LWF1dGgudGVzbGEuY29tL29hdXRoMi92My91c2VyaW5mbyJdLCJzY3AiOlsib2ZmbGluZV9hY2Nlc3MiLCJvcGVuaWQiLCJ2ZWhpY2xlX2RldmljZV9kYXRhIiwidmVoaWNsZV9sb2NhdGlvbiJdLCJhbXIiOlsicHdkIl0sImV4cCI6MTc1NTU3NDk5NCwiaWF0IjoxNzU1NTQ2MTk0LCJvdV9jb2RlIjoiRVUiLCJsb2NhbGUiOiJodS1IVSIsImFjY291bnRfdHlwZSI6InBlcnNvbiIsIm9wZW5fc291cmNlIjpmYWxzZSwiYWNjb3VudF9pZCI6IjE5YTBhZjRmLTY1ZDgtNDc2MC1hYjVmLTZjMzk3ZTViMTI4ZiIsImF1dGhfdGltZSI6MTc1NTU0NjE5NCwibm9uY2UiOiI2Mzg5MTExNDkyNjE4ODc5MzUuWVdNMllUazNORFV0T1RSaVlTMDBZMlUyTFdFNU1USXRZVEUwTnpFd056WTFabU16TkRZeFpqRTJaRE10TlRjeFpDMDBaRGN3TFRrMlptVXROMk0xWTJNNU5ERmtNV1k0In0.iMODkOXyzt0_TJfuBrojbYSU7Cx_lb8DRZ_zMz-yQxZlPUA-pITfqgqgwQEqagCUJ3wlfOSxi1OSitmxPrxr9MOT8A9KUgTOSIrPxD36JHWnBmQpbkDNqNkM4MLEbbM-95p8YnFJ0VuB9_fzz0CbJyOm_oUelA2JnNhIQ5uGfJojYPM2UKN0rUx6uMAuFgc4CslPY1P43crAXrFlH6B3D2Yk47w9Xeh-Vg_ZiX-nJqMzph_ciqYRuiySJMjM3ez7EheGy50BR_esz4muit89H3nq0rURWBN3-weauu2bcWnuYp0Nk5-zFuO3O_FKuLt-1HqYH3CAeTF2JRBJHim-hA";