6e70c4ae07
#### ⚠️ targets #10051 ## Summary of the Pull Request This PR does one big, primary thing. It removes all the constructors from any TerminalConnections, and changes them to use an `Initialize` method that accepts a `ValueSet` of properties. Why? For the upcoming window/content process work, we'll need the content process to be able to initialize the connection _in the content process_. However, the window process will be the one that knows what type of connection to make. Enter `ConnectionInformation`. This class will let us specify the class name of the type we want to create, and a set of settings to use when initializing that connection. **IMPORTANT**: As a part of this, the constructor for a connection must have 0 arguments. `RoActivateInstance` lets you just conjure a WinRT type just by class name, but that class must have a 0 arg ctor. Hence the need for `Initialize`, to actually pass the settings. We're using a `ValueSet` here because it's basically a json blob, with more steps. In the future, when extension authors want to have custom connections, we can always deserialize the json into a `ValueSet`, pass it to their connection's `Initialize`, and let then get what they need out of it. ## References * Tear-out: #1256 * Megathread: #5000 * Project: https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760298 * [x] I work here * [n/a] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments `ConnectionInformation` was included as a part of this PR, to demonstrate how this will eventually be used. `ConnectionInformation` is not _currently_ used. ## Validation Steps Performed It still builds and runs.
111 lines
3.8 KiB
C++
111 lines
3.8 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#pragma once
|
|
|
|
#include "AzureConnection.g.h"
|
|
|
|
#include <cpprest/http_client.h>
|
|
#include <cpprest/http_listener.h>
|
|
#include <cpprest/ws_client.h>
|
|
#include <mutex>
|
|
#include <condition_variable>
|
|
|
|
#include "../cascadia/inc/cppwinrt_utils.h"
|
|
#include "ConnectionStateHolder.h"
|
|
#include "AzureClient.h"
|
|
|
|
namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|
{
|
|
struct AzureConnection : AzureConnectionT<AzureConnection>, ConnectionStateHolder<AzureConnection>
|
|
{
|
|
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<std::wstring> _ReadUserInput(InputMode mode);
|
|
|
|
web::websockets::client::websocket_client _cloudShellSocket;
|
|
|
|
static std::optional<utility::string_t> _ParsePreferredShellType(const web::json::value& settingsResponse);
|
|
};
|
|
}
|
|
|
|
namespace winrt::Microsoft::Terminal::TerminalConnection::factory_implementation
|
|
{
|
|
struct AzureConnection : AzureConnectionT<AzureConnection, implementation::AzureConnection>
|
|
{
|
|
};
|
|
}
|