Fix #4976 AAD Login will not work from Azure (#5768)

- Azure token wasn't being copied into profile so expand didn't work, it spun forever
- Fixed this by saving in password/token after the connection profile copy, & refactored to be cleaner
- We should ideally ensure session notifies resolves even on fail so if there's a different error it'll break, not spin forever. Punting this part of the fix for now
- Also doesn't solve issue where we always try to connect even if user + password combo isn't saved. Will investigate / work in a separate PR on this.
This commit is contained in:
Kevin Cunnane
2019-05-31 12:47:45 -07:00
committed by GitHub
parent 5c520bc82e
commit 8786caf630

View File

@@ -16,6 +16,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { generateUuid } from 'vs/base/common/uuid';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { TreeItemCollapsibleState } from 'vs/workbench/common/views';
import { localize } from 'vs/nls';
export const SERVICE_ID = 'oeShimService';
export const IOEShimService = createDecorator<IOEShimService>(SERVICE_ID);
@@ -44,45 +45,56 @@ export class OEShimService extends Disposable implements IOEShimService {
}
private async createSession(viewId: string, providerId: string, node: ITreeItem): Promise<string> {
let deferred = new Deferred<string>();
let connProfile = new ConnectionProfile(this.capabilities, node.payload);
connProfile.saveProfile = false;
if (this.cm.providerRegistered(providerId)) {
await new Promise(async (resolve, reject) => {
await this.cm.connect(connProfile, undefined,
{ showConnectionDialogOnError: true, showFirewallRuleOnError: true, saveTheConnection: false, showDashboard: false, params: undefined },
{
onConnectSuccess: async (e, profile) => {
let existingConnection = this.cm.findExistingConnection(profile);
connProfile = new ConnectionProfile(this.capabilities, await this.cm.addSavedPassword(existingConnection));
resolve();
},
onConnectCanceled: () => {
reject('User canceled');
},
onConnectReject: undefined,
onConnectStart: undefined,
onDisconnect: undefined
});
});
connProfile = await this.connectOrPrompt(connProfile);
} else {
// Throw and expect upstream handler to notify about the error
// TODO: In the future should use extension recommendations to prompt for correct extension
throw new Error(localize('noProviderFound', "Cannot expand as the required connection provider '{0}' was not found", providerId));
}
let sessionResp = await this.oe.createNewSession(providerId, connProfile);
let disp = this.oe.onUpdateObjectExplorerNodes(e => {
if (e.connection.id === connProfile.id) {
if (e.errorMessage) {
deferred.reject();
return;
let sessionId = sessionResp.sessionId;
await new Promise((resolve, reject) => {
let listener = this.oe.onUpdateObjectExplorerNodes(e => {
if (e.connection.id === connProfile.id) {
if (e.errorMessage) {
listener.dispose();
reject(new Error(e.errorMessage));
return;
}
let rootNode = this.oe.getSession(sessionResp.sessionId).rootNode;
// this is how we know it was shimmed
if (rootNode.nodePath) {
this.nodeHandleMap.set(generateNodeMapKey(viewId, node), rootNode.nodePath);
}
}
let rootNode = this.oe.getSession(sessionResp.sessionId).rootNode;
// this is how we know it was shimmed
if (rootNode.nodePath) {
this.nodeHandleMap.set(generateNodeMapKey(viewId, node), rootNode.nodePath);
}
}
disp.dispose();
deferred.resolve(sessionResp.sessionId);
listener.dispose();
resolve(sessionResp.sessionId);
});
});
return deferred.promise;
return sessionId;
}
private async connectOrPrompt(connProfile: ConnectionProfile): Promise<ConnectionProfile> {
connProfile = await new Promise(async (resolve, reject) => {
await this.cm.connect(connProfile, undefined, { showConnectionDialogOnError: true, showFirewallRuleOnError: true, saveTheConnection: false, showDashboard: false, params: undefined }, {
onConnectSuccess: async (e, profile) => {
let existingConnection = this.cm.findExistingConnection(profile);
connProfile = new ConnectionProfile(this.capabilities, existingConnection);
connProfile = <ConnectionProfile>await this.cm.addSavedPassword(connProfile);
resolve(connProfile);
},
onConnectCanceled: () => {
reject(new Error(localize('loginCanceled', 'User canceled')));
},
onConnectReject: undefined,
onConnectStart: undefined,
onDisconnect: undefined
});
});
return connProfile;
}
public async disconnectNode(viewId: string, node: ITreeItem): Promise<boolean> {