// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. #pragma once #include "AzureConnection.g.h" #include #include #include #include #include #include "../cascadia/inc/cppwinrt_utils.h" #include "ConnectionStateHolder.h" #include "AzureClient.h" namespace winrt::Microsoft::Terminal::TerminalConnection::implementation { struct AzureConnection : AzureConnectionT, ConnectionStateHolder { static winrt::guid ConnectionType() noexcept; static bool IsAzureConnectionAvailable() noexcept; AzureConnection() = default; void Initialize(const Windows::Foundation::Collections::ValueSet& settings); void Start(); void WriteInput(hstring const& data); void Resize(uint32_t rows, uint32_t columns); void Close(); WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler); private: uint32_t _initialRows{}; uint32_t _initialCols{}; enum class AzureState { AccessStored, DeviceFlow, TenantChoice, StoreTokens, TermConnecting, TermConnected, }; AzureState _state{ AzureState::AccessStored }; wil::unique_handle _hOutputThread; DWORD _OutputThread(); void _RunAccessState(); void _RunDeviceFlowState(); void _RunTenantChoiceState(); void _RunStoreState(); void _RunConnectState(); const utility::string_t _loginUri{ U("https://login.microsoftonline.com/") }; const utility::string_t _resourceUri{ U("https://management.azure.com/") }; const utility::string_t _wantedResource{ U("https://management.core.windows.net/") }; const int _expireLimit{ 2700 }; utility::string_t _accessToken; utility::string_t _refreshToken; int _expiry{ 0 }; utility::string_t _cloudShellUri; utility::string_t _terminalID; std::vector<::Microsoft::Terminal::Azure::Tenant> _tenantList; std::optional<::Microsoft::Terminal::Azure::Tenant> _currentTenant; void _WriteStringWithNewline(const std::wstring_view str); void _WriteCaughtExceptionRecord(); web::json::value _SendRequestReturningJson(web::http::client::http_client& theClient, web::http::http_request theRequest); web::json::value _SendAuthenticatedRequestReturningJson(web::http::client::http_client& theClient, web::http::http_request theRequest); web::json::value _GetDeviceCode(); web::json::value _WaitForUser(utility::string_t deviceCode, int pollInterval, int expiresIn); void _PopulateTenantList(); void _RefreshTokens(); web::json::value _GetCloudShellUserSettings(); utility::string_t _GetCloudShell(); utility::string_t _GetTerminal(utility::string_t shellType); void _StoreCredential(); void _RemoveCredentials(); enum class InputMode { None = 0, Line }; InputMode _currentInputMode{ InputMode::None }; std::wstring _userInput; std::condition_variable _inputEvent; std::mutex _inputMutex; std::optional _ReadUserInput(InputMode mode); web::websockets::client::websocket_client _cloudShellSocket; static std::optional _ParsePreferredShellType(const web::json::value& settingsResponse); }; } namespace winrt::Microsoft::Terminal::TerminalConnection::factory_implementation { struct AzureConnection : AzureConnectionT { }; }