Fix some no unsafe assignment errors in azurecore (#22643)

This commit is contained in:
Charles Gagnon
2023-04-06 16:50:24 -07:00
committed by GitHub
parent 5ae0e3a503
commit 6a2ec12a35
10 changed files with 43 additions and 20 deletions

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
export class AzureAuthError extends Error { export class AzureAuthError extends Error {
constructor(localizedMessage: string, public readonly originalMessage: string, private readonly originalException: any) { constructor(localizedMessage: string, public readonly originalMessage: string, private readonly originalException: unknown) {
super(localizedMessage); super(localizedMessage);
} }

View File

@@ -15,8 +15,9 @@ export class AlreadyInitializedError extends Error {
} }
type DbMap = { [key: string]: string };
export class FileDatabase { export class FileDatabase {
private db: { [key: string]: string } = {}; private db: DbMap = {};
private isDirty = false; private isDirty = false;
private isSaving = false; private isSaving = false;
private isInitialized = false; private isInitialized = false;
@@ -106,7 +107,7 @@ export class FileDatabase {
} }
try { try {
this.db = JSON.parse(fileContents); this.db = JSON.parse(fileContents) as DbMap;
} catch (ex) { } catch (ex) {
Logger.error(`Error occurred when reading file database contents as JSON, ADAL cache will be reset: ${ex}`); Logger.error(`Error occurred when reading file database contents as JSON, ADAL cache will be reset: ${ex}`);
await this.createFile(); await this.createFile();

View File

@@ -7,7 +7,7 @@ import * as azdata from 'azdata';
import { AppContext } from './appContext'; import { AppContext } from './appContext';
import { AzureResourceServiceNames } from './azureResource/constants'; import { AzureResourceServiceNames } from './azureResource/constants';
import { IAzureResourceSubscriptionService } from './azureResource/interfaces'; import { IAzureResourceSubscriptionService } from './azureResource/interfaces';
import { azureResource } from 'azurecore'; import { AzureAccountProperties, azureResource } from 'azurecore';
import * as azureResourceUtils from './azureResource/utils'; import * as azureResourceUtils from './azureResource/utils';
import * as constants from './constants'; import * as constants from './constants';
import * as loc from './localizedConstants'; import * as loc from './localizedConstants';
@@ -56,7 +56,7 @@ export class AzureDataGridProvider implements azdata.DataGridProvider {
type: item.type, type: item.type,
typeDisplayName: utils.getResourceTypeDisplayName(item.type), typeDisplayName: utils.getResourceTypeDisplayName(item.type),
iconPath: utils.getResourceTypeIcon(this._appContext, item.type), iconPath: utils.getResourceTypeIcon(this._appContext, item.type),
portalEndpoint: account.properties.providerSettings.settings.portalEndpoint portalEndpoint: (account.properties as AzureAccountProperties).providerSettings.settings.portalEndpoint
}; };
}); });
items.push(...newItems); items.push(...newItems);

View File

@@ -11,7 +11,7 @@ import { AzureResourceItemType } from '../../../constants';
import { generateGuid } from '../../../utils'; import { generateGuid } from '../../../utils';
import { IAzureResourceService } from '../../../interfaces'; import { IAzureResourceService } from '../../../interfaces';
import { ResourceTreeDataProviderBase } from '../../resourceTreeDataProviderBase'; import { ResourceTreeDataProviderBase } from '../../resourceTreeDataProviderBase';
import { azureResource } from 'azurecore'; import { AzureAccountProperties, azureResource } from 'azurecore';
import * as azdata from 'azdata'; import * as azdata from 'azdata';
export class CosmosDbMongoTreeDataProvider extends ResourceTreeDataProviderBase<azureResource.AzureResourceDatabaseServer> { export class CosmosDbMongoTreeDataProvider extends ResourceTreeDataProviderBase<azureResource.AzureResourceDatabaseServer> {
@@ -52,7 +52,7 @@ export class CosmosDbMongoTreeDataProvider extends ResourceTreeDataProviderBase<
azureAccount: account.key.accountId, azureAccount: account.key.accountId,
azureTenantId: databaseServer.tenant, azureTenantId: databaseServer.tenant,
azureResourceId: databaseServer.id, azureResourceId: databaseServer.id,
azurePortalEndpoint: account.properties.providerSettings.settings.portalEndpoint azurePortalEndpoint: (account.properties as AzureAccountProperties).providerSettings.settings.portalEndpoint
}, },
childProvider: CosmosDbMongoTreeDataProvider.COSMOSDG_MONGO_PROVIDER_ID, childProvider: CosmosDbMongoTreeDataProvider.COSMOSDG_MONGO_PROVIDER_ID,
type: azdata.ExtensionNodeType.Server type: azdata.ExtensionNodeType.Server

View File

@@ -11,7 +11,7 @@ import { AzureResourceItemType } from '../../constants';
import { generateGuid } from '../../utils'; import { generateGuid } from '../../utils';
import { IAzureResourceService } from '../../interfaces'; import { IAzureResourceService } from '../../interfaces';
import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase'; import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase';
import { azureResource } from 'azurecore'; import { AzureAccountProperties, azureResource } from 'azurecore';
import { Account, ExtensionNodeType, TreeItem, connection } from 'azdata'; import { Account, ExtensionNodeType, TreeItem, connection } from 'azdata';
export class MysqlFlexibleServerTreeDataProvider extends ResourceTreeDataProviderBase<azureResource.AzureResourceDatabaseServer> { export class MysqlFlexibleServerTreeDataProvider extends ResourceTreeDataProviderBase<azureResource.AzureResourceDatabaseServer> {
@@ -54,7 +54,7 @@ export class MysqlFlexibleServerTreeDataProvider extends ResourceTreeDataProvide
azureAccount: account.key.accountId, azureAccount: account.key.accountId,
azureTenantId: databaseServer.tenant, azureTenantId: databaseServer.tenant,
azureResourceId: databaseServer.id, azureResourceId: databaseServer.id,
azurePortalEndpoint: account.properties.providerSettings.settings.portalEndpoint azurePortalEndpoint: (account.properties as AzureAccountProperties).providerSettings.settings.portalEndpoint
}, },
childProvider: MysqlFlexibleServerTreeDataProvider.MYSQL_FLEXIBLE_SERVER_PROVIDER_ID, childProvider: MysqlFlexibleServerTreeDataProvider.MYSQL_FLEXIBLE_SERVER_PROVIDER_ID,
type: ExtensionNodeType.Server type: ExtensionNodeType.Server

View File

@@ -11,6 +11,7 @@ import { AzureResourceErrorMessageUtil } from '../utils';
import { ResourceGraphClient } from '@azure/arm-resourcegraph'; import { ResourceGraphClient } from '@azure/arm-resourcegraph';
import { AzureAccount, azureResource } from 'azurecore'; import { AzureAccount, azureResource } from 'azurecore';
import { Logger } from '../../utils/Logger'; import { Logger } from '../../utils/Logger';
import { ErrorResponse } from '@azure/arm-resourcegraph/esm/models';
export abstract class ResourceTreeDataProviderBase<T extends azureResource.AzureResource> implements azureResource.IAzureResourceTreeDataProvider { export abstract class ResourceTreeDataProviderBase<T extends azureResource.AzureResource> implements azureResource.IAzureResourceTreeDataProvider {
public browseConnectionMode: boolean = false; public browseConnectionMode: boolean = false;
@@ -78,7 +79,7 @@ export async function queryGraphResources<T extends GraphData>(resourceClient: R
skipToken: skipToken skipToken: skipToken
} }
}); });
const resources: T[] = response.data; const resources: T[] = response.data as T[];
totalProcessed += resources.length; totalProcessed += resources.length;
allResources.push(...resources); allResources.push(...resources);
if (response.skipToken && totalProcessed < response.totalRecords) { if (response.skipToken && totalProcessed < response.totalRecords) {
@@ -91,7 +92,7 @@ export async function queryGraphResources<T extends GraphData>(resourceClient: R
try { try {
if (err.response?.body) { if (err.response?.body) {
// The response object contains more useful error info than the error originally comes back with // The response object contains more useful error info than the error originally comes back with
const response = JSON.parse(err.response.body); const response = JSON.parse(err.response.body) as ErrorResponse;
if (response.error?.details && Array.isArray(response.error.details) && response.error.details.length > 0) { if (response.error?.details && Array.isArray(response.error.details) && response.error.details.length > 0) {
if (response.error.details[0].message) { if (response.error.details[0].message) {
err.message = `${response.error.details[0].message}\n${err.message}`; err.message = `${response.error.details[0].message}\n${err.message}`;

View File

@@ -97,7 +97,7 @@ export class AzureResourceService {
} }
for (const extension of extensions.all) { for (const extension of extensions.all) {
const contributes = extension.packageJSON && extension.packageJSON.contributes; const contributes = extension.packageJSON.contributes as { [key: string]: string } | undefined;
if (!contributes) { if (!contributes) {
continue; continue;
} }

View File

@@ -42,6 +42,20 @@ const handleNeverUsed = async (): Promise<void> => {
} }
}; };
type CloudConsoleSettingsResponse = {
properties?: {
preferredShellType?: string,
preferredLocation?: string
}
}
type CloudConsoleRequestResponse = {
properties?: {
provisioningState: string,
uri: string
}
}
export class AzureTerminalService implements IAzureTerminalService { export class AzureTerminalService implements IAzureTerminalService {
private readonly apiVersion = '?api-version=2018-10-01'; private readonly apiVersion = '?api-version=2018-10-01';
@@ -66,7 +80,7 @@ export class AzureTerminalService implements IAzureTerminalService {
const metadata = account.properties.providerSettings; const metadata = account.properties.providerSettings;
const userSettingsUri = this.getConsoleUserSettingsUri(metadata.settings.armResource.endpoint); const userSettingsUri = this.getConsoleUserSettingsUri(metadata.settings.armResource.endpoint);
let userSettingsResult: AxiosResponse<any>; let userSettingsResult: AxiosResponse<CloudConsoleSettingsResponse>;
try { try {
userSettingsResult = await axios.get(userSettingsUri, settings); userSettingsResult = await axios.get(userSettingsUri, settings);
} catch (ex) {// Log as info as exception is handled } catch (ex) {// Log as info as exception is handled
@@ -83,7 +97,7 @@ export class AzureTerminalService implements IAzureTerminalService {
settings.headers!['x-ms-console-preferred-location'] = preferredLocation; settings.headers!['x-ms-console-preferred-location'] = preferredLocation;
} }
let provisionResult: AxiosResponse<any>; let provisionResult: AxiosResponse<CloudConsoleRequestResponse>;
try { try {
provisionResult = await axios.put(consoleRequestUri, {}, settings); provisionResult = await axios.put(consoleRequestUri, {}, settings);
} catch (ex) {// Log as info as exception is handled } catch (ex) {// Log as info as exception is handled
@@ -93,7 +107,7 @@ export class AzureTerminalService implements IAzureTerminalService {
} }
if (provisionResult.data?.properties?.provisioningState !== 'Succeeded') { if (provisionResult.data?.properties?.provisioningState !== 'Succeeded') {
throw new Error(provisionResult.data); throw new Error(JSON.stringify(provisionResult.data));
} }
const consoleUri = provisionResult.data.properties.uri; const consoleUri = provisionResult.data.properties.uri;
@@ -143,6 +157,13 @@ export class AzureTerminalService implements IAzureTerminalService {
} }
} }
type TerminalResponse = {
socketUri?: string | undefined;
error?: {
message: string
}
}
class AzureTerminal implements vscode.Pseudoterminal { class AzureTerminal implements vscode.Pseudoterminal {
private readonly writeEmitter: vscode.EventEmitter<string>; private readonly writeEmitter: vscode.EventEmitter<string>;
public readonly onDidWrite: vscode.Event<string>; public readonly onDidWrite: vscode.Event<string>;
@@ -222,7 +243,7 @@ class AzureTerminal implements vscode.Pseudoterminal {
private async establishTerminal(dimensions: vscode.TerminalDimensions | undefined): Promise<string | undefined> { private async establishTerminal(dimensions: vscode.TerminalDimensions | undefined): Promise<string | undefined> {
let terminalResult: AxiosResponse<any>; let terminalResult: AxiosResponse<TerminalResponse>;
try { try {
const url = dimensions ? const url = dimensions ?
`${this.consoleUri}/terminals?rows=${dimensions.rows}&cols=${dimensions.columns}&shell=${this.shell}` `${this.consoleUri}/terminals?rows=${dimensions.rows}&cols=${dimensions.columns}&shell=${this.shell}`
@@ -247,8 +268,7 @@ class AzureTerminal implements vscode.Pseudoterminal {
} }
if (!terminalUri) { if (!terminalUri) {
Logger.error(terminalResult); throw Error(JSON.stringify(terminalResult.data));
throw Error(terminalResult.data);
} }
return terminalUri; return terminalUri;

View File

@@ -118,7 +118,7 @@ describe('Azure Authentication', function () {
}); });
azureAuthCodeGrant.setup(x => x.refreshTokenAdal(mockTenant, provider.settings.ossRdbmsResource!, mockRefreshToken)).returns((): Promise<OAuthTokenResponse> => { azureAuthCodeGrant.setup(x => x.refreshTokenAdal(mockTenant, provider.settings.ossRdbmsResource!, mockRefreshToken)).returns((): Promise<OAuthTokenResponse> => {
const mockToken: AccessToken = JSON.parse(JSON.stringify(mockAccessToken)); const mockToken: AccessToken = JSON.parse(JSON.stringify(mockAccessToken)) as AccessToken;
delete (mockToken as any).invalidData; delete (mockToken as any).invalidData;
return Promise.resolve({ return Promise.resolve({
accessToken: mockToken accessToken: mockToken
@@ -164,7 +164,7 @@ describe('Azure Authentication', function () {
}); });
}); });
azureAuthCodeGrant.setup(x => x.refreshTokenAdal(mockTenant, provider.settings.microsoftResource!, mockRefreshToken)).returns((): Promise<OAuthTokenResponse> => { azureAuthCodeGrant.setup(x => x.refreshTokenAdal(mockTenant, provider.settings.microsoftResource!, mockRefreshToken)).returns((): Promise<OAuthTokenResponse> => {
const mockToken: AccessToken = JSON.parse(JSON.stringify(mockAccessToken)); const mockToken: AccessToken = JSON.parse(JSON.stringify(mockAccessToken)) as AccessToken;
delete (mockToken as any).invalidData; delete (mockToken as any).invalidData;
return Promise.resolve({ return Promise.resolve({
accessToken: mockToken accessToken: mockToken

View File

@@ -98,6 +98,7 @@ function sanitize(objOrArray: any): string {
} }
function sanitizeImpl(obj: any): string { function sanitizeImpl(obj: any): string {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
obj = Object.assign({}, obj); obj = Object.assign({}, obj);
delete obj.domains; // very long and not really useful delete obj.domains; // very long and not really useful
// shorten all tokens since we don't usually need the exact values and there's security concerns if they leaked // shorten all tokens since we don't usually need the exact values and there's security concerns if they leaked