From 2eb93ed2a7e83a40f908ad134a4f75b05c39be1f Mon Sep 17 00:00:00 2001 From: khvitaly Date: Sun, 8 Nov 2020 17:43:15 +0200 Subject: [PATCH 1/3] 7056: provide informative error if Azure CLI user settings miss preferred shell type --- .../TerminalConnection/AzureConnection.cpp | 32 +++++++++++++++++-- .../TerminalConnection/AzureConnection.h | 2 ++ .../Resources/en-US/Resources.resw | 4 +++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalConnection/AzureConnection.cpp b/src/cascadia/TerminalConnection/AzureConnection.cpp index b8c5e31a0b9..37ad67fca58 100644 --- a/src/cascadia/TerminalConnection/AzureConnection.cpp +++ b/src/cascadia/TerminalConnection/AzureConnection.cpp @@ -687,6 +687,27 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation _state = AzureState::TermConnecting; } + // Method description: + // - Helper function to parse the preferred shell type from user settings returned by cloud console API. + // We need this function because the field might be missing in the settings + // created with old versions of cloud console API. + std::optional AzureConnection::_ParsePreferredShellType(const web::json::value& settingsResponse) + { + if (!settingsResponse.has_object_field(L"properties")) + { + return std::nullopt; + } + + const auto userSettings = settingsResponse.at(L"properties"); + if (!userSettings.has_string_field(L"preferredShellType")) + { + return std::nullopt; + } + + const auto preferredShellTypeValue = userSettings.at(L"preferredShellType"); + return std::optional(preferredShellTypeValue.as_string()); + } + // Method description: // - helper function to connect the user to the Azure cloud shell void AzureConnection::_RunConnectState() @@ -700,15 +721,22 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation return; } + const auto shellType = _ParsePreferredShellType(settingsResponse); + if (!shellType.has_value()) + { + _WriteStringWithNewline(RS_(L"AzureInvalidUserSettings")); + _transitionToState(ConnectionState::Failed); + return; + } + // Request for a cloud shell _WriteStringWithNewline(RS_(L"AzureRequestingCloud")); _cloudShellUri = _GetCloudShell(); _WriteStringWithNewline(RS_(L"AzureSuccess")); // Request for a terminal for said cloud shell - const auto shellType = settingsResponse.at(L"properties").at(L"preferredShellType").as_string(); _WriteStringWithNewline(RS_(L"AzureRequestingTerminal")); - const auto socketUri = _GetTerminal(shellType); + const auto socketUri = _GetTerminal(*shellType); _TerminalOutputHandlers(L"\r\n"); // Step 8: connecting to said terminal diff --git a/src/cascadia/TerminalConnection/AzureConnection.h b/src/cascadia/TerminalConnection/AzureConnection.h index 4db0a9619b4..b2afd99ab2e 100644 --- a/src/cascadia/TerminalConnection/AzureConnection.h +++ b/src/cascadia/TerminalConnection/AzureConnection.h @@ -95,6 +95,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation std::optional _ReadUserInput(InputMode mode); web::websockets::client::websocket_client _cloudShellSocket; + + static std::optional _ParsePreferredShellType(const web::json::value& settingsResponse); }; } diff --git a/src/cascadia/TerminalConnection/Resources/en-US/Resources.resw b/src/cascadia/TerminalConnection/Resources/en-US/Resources.resw index b0abd44a0cb..9fbe23c6523 100644 --- a/src/cascadia/TerminalConnection/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalConnection/Resources/en-US/Resources.resw @@ -148,6 +148,10 @@ You have not set up your cloud shell account yet. Please go to https://shell.azure.com to set it up. {Locked="https://shell.azure.com"} This URL should not be localized. Everything else should. + + Your cloud shell account misses some mandatory settings. Please go to https://shell.azure.com to set it up. + {Locked="https://shell.azure.com"} This URL should not be localized. Everything else should. + Do you want to save these connection settings for future logins? [{0}/{1}] {0} and {1} will be replaced with AzureUserEntry_Yes and AzureUserEntry_No. They are single-character shorthands for "yes" and "no" in this language. From 9520f5b1d8bbe02c32abfb5161585573f5691ef4 Mon Sep 17 00:00:00 2001 From: khvitaly Date: Mon, 9 Nov 2020 21:39:17 +0200 Subject: [PATCH 2/3] 7056: fallback to powershell if no preferred shell is set --- .../TerminalConnection/AzureConnection.cpp | 26 +++++++------------ .../Resources/en-US/Resources.resw | 4 --- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/cascadia/TerminalConnection/AzureConnection.cpp b/src/cascadia/TerminalConnection/AzureConnection.cpp index 37ad67fca58..34895b7b268 100644 --- a/src/cascadia/TerminalConnection/AzureConnection.cpp +++ b/src/cascadia/TerminalConnection/AzureConnection.cpp @@ -693,19 +693,17 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // created with old versions of cloud console API. std::optional AzureConnection::_ParsePreferredShellType(const web::json::value& settingsResponse) { - if (!settingsResponse.has_object_field(L"properties")) + if (settingsResponse.has_object_field(L"properties")) { - return std::nullopt; - } - - const auto userSettings = settingsResponse.at(L"properties"); - if (!userSettings.has_string_field(L"preferredShellType")) - { - return std::nullopt; + const auto userSettings = settingsResponse.at(L"properties"); + if (userSettings.has_string_field(L"preferredShellType")) + { + const auto preferredShellTypeValue = userSettings.at(L"preferredShellType"); + return preferredShellTypeValue.as_string(); + } } - const auto preferredShellTypeValue = userSettings.at(L"preferredShellType"); - return std::optional(preferredShellTypeValue.as_string()); + return std::nullopt; } // Method description: @@ -722,12 +720,6 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation } const auto shellType = _ParsePreferredShellType(settingsResponse); - if (!shellType.has_value()) - { - _WriteStringWithNewline(RS_(L"AzureInvalidUserSettings")); - _transitionToState(ConnectionState::Failed); - return; - } // Request for a cloud shell _WriteStringWithNewline(RS_(L"AzureRequestingCloud")); @@ -736,7 +728,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation // Request for a terminal for said cloud shell _WriteStringWithNewline(RS_(L"AzureRequestingTerminal")); - const auto socketUri = _GetTerminal(*shellType); + const auto socketUri = _GetTerminal(shellType.value_or(L"pwsh")); _TerminalOutputHandlers(L"\r\n"); // Step 8: connecting to said terminal diff --git a/src/cascadia/TerminalConnection/Resources/en-US/Resources.resw b/src/cascadia/TerminalConnection/Resources/en-US/Resources.resw index 9fbe23c6523..b0abd44a0cb 100644 --- a/src/cascadia/TerminalConnection/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalConnection/Resources/en-US/Resources.resw @@ -148,10 +148,6 @@ You have not set up your cloud shell account yet. Please go to https://shell.azure.com to set it up. {Locked="https://shell.azure.com"} This URL should not be localized. Everything else should. - - Your cloud shell account misses some mandatory settings. Please go to https://shell.azure.com to set it up. - {Locked="https://shell.azure.com"} This URL should not be localized. Everything else should. - Do you want to save these connection settings for future logins? [{0}/{1}] {0} and {1} will be replaced with AzureUserEntry_Yes and AzureUserEntry_No. They are single-character shorthands for "yes" and "no" in this language. From 94d71ce32244ceda993dea36ddf98f4828228b74 Mon Sep 17 00:00:00 2001 From: khvitaly Date: Mon, 9 Nov 2020 21:43:36 +0200 Subject: [PATCH 3/3] 7056: move parsing logic to minimize PR diff --- src/cascadia/TerminalConnection/AzureConnection.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cascadia/TerminalConnection/AzureConnection.cpp b/src/cascadia/TerminalConnection/AzureConnection.cpp index 34895b7b268..9bddedb958b 100644 --- a/src/cascadia/TerminalConnection/AzureConnection.cpp +++ b/src/cascadia/TerminalConnection/AzureConnection.cpp @@ -719,14 +719,13 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation return; } - const auto shellType = _ParsePreferredShellType(settingsResponse); - // Request for a cloud shell _WriteStringWithNewline(RS_(L"AzureRequestingCloud")); _cloudShellUri = _GetCloudShell(); _WriteStringWithNewline(RS_(L"AzureSuccess")); // Request for a terminal for said cloud shell + const auto shellType = _ParsePreferredShellType(settingsResponse); _WriteStringWithNewline(RS_(L"AzureRequestingTerminal")); const auto socketUri = _GetTerminal(shellType.value_or(L"pwsh")); _TerminalOutputHandlers(L"\r\n");