Large cleanup of AzureCore - Introduction of getAccountSecurityToken and deprecation of getSecurityToken (#11446)

* do a large cleanup of azurecore

* Fix tests

* Rework Device Code

* Fix tests

* Fix AE scenario

* Fix firewall rule - clenaup logging

* Shorthand syntax

* Fix firewall tests

* Start on tests for azureAuth

* Add more tests

* Address comments

* Add a few more important tests

* Don't throw error on old code

* Fill in todo
This commit is contained in:
Amir Omidi
2020-07-22 15:03:42 -07:00
committed by GitHub
parent a61b85c9ff
commit 587abd43c2
40 changed files with 1045 additions and 895 deletions

View File

@@ -813,8 +813,8 @@ export class ConnectionManagementService extends Disposable implements IConnecti
const accounts = await this._accountManagementService.getAccounts();
const azureAccounts = accounts.filter(a => a.key.providerId.startsWith('azure'));
if (azureAccounts && azureAccounts.length > 0) {
let accountName = (connection.authenticationType === Constants.azureMFA || connection.authenticationType === Constants.azureMFAAndUser) ? connection.azureAccount : connection.userName;
let account = find(azureAccounts, account => account.key.accountId === accountName);
let accountId = (connection.authenticationType === Constants.azureMFA || connection.authenticationType === Constants.azureMFAAndUser) ? connection.azureAccount : connection.userName;
let account = find(azureAccounts, account => account.key.accountId === accountId);
if (account) {
this._logService.debug(`Getting security token for Azure account ${account.key.accountId}`);
if (account.isStale) {
@@ -827,26 +827,17 @@ export class ConnectionManagementService extends Disposable implements IConnecti
return false;
}
}
const tokensByTenant = await this._accountManagementService.getSecurityToken(account, azureResource);
this._logService.debug(`Got tokens for tenants [${Object.keys(tokensByTenant).join(',')}]`);
let token: string;
const tenantId = connection.azureTenantId;
if (tenantId && tokensByTenant[tenantId]) {
token = tokensByTenant[tenantId].token;
} else {
this._logService.debug(`No security token found for specific tenant ${tenantId} - falling back to first one`);
const tokens = values(tokensByTenant);
if (tokens.length === 0) {
this._logService.info(`No security tokens found for account`);
return false;
}
token = tokens[0].token;
const token = await this._accountManagementService.getAccountSecurityToken(account, tenantId, azureResource);
this._logService.debug(`Got token for tenant ${token}`);
if (!token) {
this._logService.info(`No security tokens found for account`);
}
connection.options['azureAccountToken'] = token;
connection.options['azureAccountToken'] = token.token;
connection.options['password'] = '';
return true;
} else {
this._logService.info(`Could not find Azure account with name ${accountName}`);
this._logService.info(`Could not find Azure account with name ${accountId}`);
}
} else {
this._logService.info(`Could not find any Azure accounts from accounts : [${accounts.map(a => `${a.key.accountId} (${a.key.providerId})`).join(',')}]`);

View File

@@ -6,7 +6,7 @@
import 'vs/css!./media/sqlConnection';
import { Button } from 'sql/base/browser/ui/button/button';
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
import { SelectBox, SelectOptionItemSQL } from 'sql/base/browser/ui/selectBox/selectBox';
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox';
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
import * as DialogHelper from 'sql/workbench/browser/modal/dialogHelper';
@@ -520,12 +520,18 @@ export class ConnectionWidget extends lifecycle.Disposable {
let oldSelection = this._azureAccountDropdown.value;
const accounts = await this._accountManagementService.getAccounts();
this._azureAccountList = accounts.filter(a => a.key.providerId.startsWith('azure'));
let accountDropdownOptions = this._azureAccountList.map(account => account.displayInfo.displayName);
let accountDropdownOptions: SelectOptionItemSQL[] = this._azureAccountList.map(account => {
return {
text: account.displayInfo.displayName,
value: account.key.accountId
} as SelectOptionItemSQL;
});
if (accountDropdownOptions.length === 0) {
// If there are no accounts add a blank option so that add account isn't automatically selected
accountDropdownOptions.unshift('');
accountDropdownOptions.unshift({ text: '', value: '' });
}
accountDropdownOptions.push(this._addAzureAccountMessage);
accountDropdownOptions.push({ text: this._addAzureAccountMessage, value: this._addAzureAccountMessage });
this._azureAccountDropdown.setOptions(accountDropdownOptions);
this._azureAccountDropdown.selectWithOptionName(oldSelection);
}

View File

@@ -1299,6 +1299,7 @@ suite('SQL ConnectionManagementService tests', () => {
let servername = 'test-database.database.windows.net';
azureConnectionProfile.serverName = servername;
let providerId = 'azure_PublicCloud';
azureConnectionProfile.azureTenantId = 'testTenant';
// Set up the account management service to return a token for the given user
accountManagementService.setup(x => x.getAccountsForProvider(TypeMoq.It.isAny())).returns(providerId => Promise.resolve<azdata.Account[]>([
@@ -1327,10 +1328,9 @@ suite('SQL ConnectionManagementService tests', () => {
]);
});
let testToken = 'testToken';
accountManagementService.setup(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
azure_publicCloud: {
token: testToken
}
accountManagementService.setup(x => x.getAccountSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
token: testToken,
tokenType: 'Bearer'
}));
connectionStore.setup(x => x.addSavedPassword(TypeMoq.It.is(profile => profile.authenticationType === 'AzureMFA'))).returns(profile => Promise.resolve({
profile: profile,
@@ -1384,11 +1384,8 @@ suite('SQL ConnectionManagementService tests', () => {
]);
});
let testToken = 'testToken';
let returnedTokens = {};
returnedTokens['azure_publicCloud'] = { token: 'badToken' };
returnedTokens[azureTenantId] = { token: testToken };
accountManagementService.setup(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(returnedTokens));
let returnedToken = { token: 'testToken', tokenType: 'Bearer' };
accountManagementService.setup(x => x.getAccountSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(returnedToken));
connectionStore.setup(x => x.addSavedPassword(TypeMoq.It.is(profile => profile.authenticationType === 'AzureMFA'))).returns(profile => Promise.resolve({
profile: profile,
savedCred: false
@@ -1399,7 +1396,7 @@ suite('SQL ConnectionManagementService tests', () => {
// Then the returned profile has the account token set corresponding to the requested tenant
assert.equal(profileWithCredentials.userName, azureConnectionProfile.userName);
assert.equal(profileWithCredentials.options['azureAccountToken'], testToken);
assert.equal(profileWithCredentials.options['azureAccountToken'], returnedToken.token);
});
test('getConnections test', () => {