c186c7d683
This commit fixes a number of problems and code quality/health issues with the AzureConnection. This is a general tidying-up of the azure connection. It improves error logging (like: it actually emits error logs...) and retry logic and the state machine and it audits the exit points of the state machine for exceptions and removes the HRESULT returns (so they either succeed and transition to a new state or throw an exception or are going down anyway). There's also a change in here that changes how we display tenants. It adds the "default domain" to the name, so that instead of seeing this: Conhost (aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa) Default Directory (bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb) you see this Conhost (conhost.onmicrosoft.com) Default Directory (dustinhowett.onmicrosoft.com) Changes: * rework tenant/tenant storage and fix display names Switch to the 2020 tenant API. Instead of passing around four loose variables, create a Tenant class and use that for packing/unpacking into/out of json (and the windows credential store, where we "cleverly" used json for the tenant info there too). When displaying a tenant, use its display name if there is one, the unknown resource string if there isn't, and the default domain if there is one and the ID if there isn't. Fixes #5325. * use {fmt} for formatting request bodies * remove dead strings * rework/rename Request/HeaderHelper to Send(Authenticated)ReqReturningJson * rewrite polling to use std::chrono * remove HR returns from state machine * rename state handlers from _XHelper to _RunXState * cleanup namespaces, prefix user input with >, remove namespaces * Rework error handling - _RequestHelper no longer eats exceptions. - Delete the "no internet" error message. - Wrap exceptions coming out of Azure API in a well-known type. - Catch by type. - Extract error codes for known failures (keep polling, invalid grant). - When we get an Invalid Grant, dispose of the cached refresh token and force the user to log in again. - Catch all printable exceptions and print them. - Remove the NoConnect state completely -- just bail out when an exception hits the toplevel of the output thread. - Move 3x logic into _RefreshTokens and pop exceptions out of it. - Begin abstracting into AzureClient Fixes #5325 (by addressing its chief complaint). Fixes #4803 (by triggering auth flow again if the token expires). Improves diagnosability for #4575.
54 lines
1.6 KiB
C++
54 lines
1.6 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#pragma once
|
|
|
|
#include "cpprest/json.h"
|
|
|
|
namespace Microsoft::Terminal::Azure
|
|
{
|
|
class AzureException : public std::runtime_error
|
|
{
|
|
std::wstring _code;
|
|
|
|
public:
|
|
static bool IsErrorPayload(const web::json::value& errorObject)
|
|
{
|
|
return errorObject.has_string_field(L"error");
|
|
}
|
|
|
|
AzureException(const web::json::value& errorObject) :
|
|
runtime_error(til::u16u8(errorObject.at(L"error_description").as_string())), // surface the human-readable description as .what()
|
|
_code(errorObject.at(L"error").as_string())
|
|
{
|
|
}
|
|
|
|
std::wstring_view GetCode() const noexcept
|
|
{
|
|
return _code;
|
|
}
|
|
};
|
|
|
|
namespace ErrorCodes
|
|
{
|
|
static constexpr std::wstring_view AuthorizationPending{ L"authorization_pending" };
|
|
static constexpr std::wstring_view InvalidGrant{ L"invalid_grant" };
|
|
}
|
|
|
|
struct Tenant
|
|
{
|
|
std::wstring ID;
|
|
std::optional<std::wstring> DisplayName;
|
|
std::optional<std::wstring> DefaultDomain;
|
|
};
|
|
}
|
|
|
|
#define THROW_IF_AZURE_ERROR(payload) \
|
|
do \
|
|
{ \
|
|
if (AzureException::IsErrorPayload((payload))) \
|
|
{ \
|
|
throw AzureException((payload)); \
|
|
} \
|
|
} while (0)
|