Merge from vscode 2e5312cd61ff99c570299ecc122c52584265eda2

This commit is contained in:
ADS Merger
2020-04-23 02:50:35 +00:00
committed by Anthony Dresser
parent 3603f55d97
commit 7f1d8fc32f
659 changed files with 22709 additions and 12497 deletions

View File

@@ -25,7 +25,10 @@ interface IToken {
expiresAt?: number; // UNIX epoch time at which token will expire
refreshToken: string;
accountName: string;
account: {
displayName: string;
id: string;
};
scope: string;
sessionId: string; // The account id + the scope
}
@@ -44,7 +47,10 @@ interface IStoredSession {
id: string;
refreshToken: string;
scope: string; // Scopes are alphabetized and joined with a space
accountName: string;
account: {
displayName: string,
id: string
}
}
function parseQuery(uri: vscode.Uri) {
@@ -76,6 +82,9 @@ export class AzureActiveDirectoryService {
}
public async initialize(): Promise<void> {
// TODO remove, temporary migration
await keychain.migrateToken();
const storedData = await keychain.getToken();
if (storedData) {
try {
@@ -90,7 +99,10 @@ export class AzureActiveDirectoryService {
this._tokens.push({
accessToken: undefined,
refreshToken: session.refreshToken,
accountName: session.accountName,
account: {
displayName: session.account.displayName,
id: session.account.id
},
scope: session.scope,
sessionId: session.id
});
@@ -122,7 +134,7 @@ export class AzureActiveDirectoryService {
id: token.sessionId,
refreshToken: token.refreshToken,
scope: token.scope,
accountName: token.accountName
account: token.account
};
});
@@ -196,7 +208,7 @@ export class AzureActiveDirectoryService {
return {
id: token.sessionId,
getAccessToken: () => this.resolveAccessToken(token),
accountName: token.accountName,
account: token.account,
scopes: token.scope.split(' ')
};
}
@@ -220,8 +232,6 @@ export class AzureActiveDirectoryService {
} catch (e) {
throw new Error('Unavailable due to network problems');
}
throw new Error('Unavailable due to network problems');
}
private getTokenClaims(accessToken: string): ITokenClaims {
@@ -416,7 +426,10 @@ export class AzureActiveDirectoryService {
refreshToken: json.refresh_token,
scope,
sessionId: existingId || `${claims.tid}/${(claims.oid || (claims.altsecid || '' + claims.ipd || ''))}/${uuid()}`,
accountName: claims.email || claims.unique_name || 'user@example.com'
account: {
displayName: claims.email || claims.unique_name || 'user@example.com',
id: `${claims.tid}/${(claims.oid || (claims.altsecid || '' + claims.ipd || ''))}`
}
};
}

View File

@@ -6,12 +6,15 @@
import * as vscode from 'vscode';
import { AzureActiveDirectoryService, onDidChangeSessions } from './AADHelper';
import * as nls from 'vscode-nls';
import TelemetryReporter from 'vscode-extension-telemetry';
const localize = nls.loadMessageBundle();
export const DEFAULT_SCOPES = 'https://management.core.windows.net/.default offline_access';
export async function activate(context: vscode.ExtensionContext) {
const { name, version, aiKey } = require('../package.json') as { name: string, version: string, aiKey: string };
const telemetryReporter = new TelemetryReporter(name, version, aiKey);
const loginService = new AzureActiveDirectoryService();
@@ -24,18 +27,24 @@ export async function activate(context: vscode.ExtensionContext) {
getSessions: () => Promise.resolve(loginService.sessions),
login: async (scopes: string[]) => {
try {
telemetryReporter.sendTelemetryEvent('login');
await loginService.login(scopes.sort().join(' '));
const session = loginService.sessions[loginService.sessions.length - 1];
onDidChangeSessions.fire({ added: [session.id], removed: [], changed: [] });
return loginService.sessions[0]!;
} catch (e) {
telemetryReporter.sendTelemetryEvent('loginFailed');
throw e;
}
},
logout: async (id: string) => {
await loginService.logout(id);
onDidChangeSessions.fire({ added: [], removed: [id], changed: [] });
vscode.window.showInformationMessage(localize('signedOut', "Successfully signed out."));
try {
telemetryReporter.sendTelemetryEvent('logout');
await loginService.logout(id);
onDidChangeSessions.fire({ added: [], removed: [id], changed: [] });
} catch (e) {
telemetryReporter.sendTelemetryEvent('logoutFailed');
}
}
}));
@@ -60,7 +69,7 @@ export async function activate(context: vscode.ExtensionContext) {
const selectedSession = await vscode.window.showQuickPick(sessions.map(session => {
return {
id: session.id,
label: session.accountName
label: session.account.displayName
};
}));

View File

@@ -28,7 +28,7 @@ export type Keytar = {
deletePassword: typeof keytarType['deletePassword'];
};
const SERVICE_ID = `${vscode.env.uriScheme}-vscode.login`;
const SERVICE_ID = `${vscode.env.uriScheme}-microsoft.login`;
const ACCOUNT_ID = 'account';
export class Keychain {
@@ -43,13 +43,38 @@ export class Keychain {
this.keytar = keytar;
}
// TODO remove, temporary migration
async migrateToken(): Promise<void> {
const oldServiceId = `${vscode.env.uriScheme}-vscode.login`;
try {
const data = await this.keytar.getPassword(oldServiceId, ACCOUNT_ID);
if (data) {
Logger.info('Migrating token...');
this.setToken(data);
await this.keytar.deletePassword(oldServiceId, ACCOUNT_ID);
Logger.info('Migration successful');
}
} catch (e) {
Logger.error(`Migrating token failed: ${e}`);
}
}
async setToken(token: string): Promise<void> {
try {
Logger.trace('Writing to keychain', token);
return await this.keytar.setPassword(SERVICE_ID, ACCOUNT_ID, token);
} catch (e) {
// Ignore
Logger.error(`Setting token failed: ${e}`);
// Temporary fix for #94005
// This happens when processes write simulatenously to the keychain, most
// likely when trying to refresh the token. Ignore the error since additional
// writes after the first one do not matter. Should actually be fixed upstream.
if (e.message === 'The specified item already exists in the keychain.') {
return;
}
const troubleshooting = localize('troubleshooting', "Troubleshooting Guide");
const result = await vscode.window.showErrorMessage(localize('keychainWriteError', "Writing login information to the keychain failed with error '{0}'.", e.message), troubleshooting);
if (result === troubleshooting) {

View File

@@ -17,7 +17,7 @@ class Log {
private level: Level;
constructor() {
this.output = vscode.window.createOutputChannel('Account');
this.output = vscode.window.createOutputChannel('Microsoft Authentication');
this.level = vscode.workspace.getConfiguration('microsoftAccount').get('logLevel') || Level.Info;
vscode.workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('microsoftAccount.logLevel')) {