Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instrument Microsoft account type #180573

Merged
merged 1 commit into from
Apr 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 36 additions & 29 deletions extensions/microsoft-authentication/src/AADHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,20 @@ import { LoopbackAuthServer } from './node/authServer';
import { base64Decode } from './node/buffer';
import { fetching } from './node/fetch';
import { UriEventHandler } from './UriEventHandler';
import TelemetryReporter from '@vscode/extension-telemetry';

const redirectUrl = 'https://vscode.dev/redirect';
const defaultLoginEndpointUrl = 'https://login.microsoftonline.com/';
const DEFAULT_CLIENT_ID = 'aebc6443-996d-45c2-90f0-388ff96faa56';
const DEFAULT_TENANT = 'organizations';
const MSA_TID = '9188040d-6c67-4c5b-b112-36a304b66dad';
const MSA_PASSTHRU_TID = 'f8cdef31-a31e-4b4a-93e4-5f571e91255a';

const enum MicrosoftAccountType {
AAD = 'aad',
MSA = 'msa',
Unknown = 'unknown'
}

interface IToken {
accessToken?: string; // When unable to refresh due to network problems, the access token becomes undefined
Expand All @@ -30,6 +39,7 @@ interface IToken {
account: {
label: string;
id: string;
type: MicrosoftAccountType;
};
scope: string;
sessionId: string; // The account id + the scope
Expand All @@ -40,8 +50,7 @@ export interface IStoredSession {
refreshToken: string;
scope: string; // Scopes are alphabetized and joined with a space
account: {
label?: string;
displayName?: string;
label: string;
id: string;
};
endpoint: string | undefined;
Expand Down Expand Up @@ -89,9 +98,10 @@ export class AzureActiveDirectoryService {

constructor(
private readonly _logger: vscode.LogOutputChannel,
private readonly _context: vscode.ExtensionContext,
_context: vscode.ExtensionContext,
private readonly _uriHandler: UriEventHandler,
private readonly _tokenStorage: BetterTokenStorage<IStoredSession>,
private readonly _telemetryReporter: TelemetryReporter,
private readonly _loginEndpointUrl: string = defaultLoginEndpointUrl
) {
_context.subscriptions.push(this._tokenStorage.onDidChangeInOtherWindow((e) => this.checkForUpdates(e)));
Expand Down Expand Up @@ -122,8 +132,8 @@ export class AzureActiveDirectoryService {
accessToken: undefined,
refreshToken: session.refreshToken,
account: {
label: session.account.label ?? session.account.displayName!,
id: session.account.id
...session.account,
type: MicrosoftAccountType.Unknown
},
scope: session.scope,
sessionId: session.id
Expand All @@ -135,8 +145,8 @@ export class AzureActiveDirectoryService {
accessToken: undefined,
refreshToken: session.refreshToken,
account: {
label: session.account.label ?? session.account.displayName!,
id: session.account.id
...session.account,
type: MicrosoftAccountType.Unknown
},
scope: session.scope,
sessionId: session.id
Expand All @@ -150,8 +160,25 @@ export class AzureActiveDirectoryService {
if (res.status === 'rejected') {
this._logger.error(`Failed to initialize stored data: ${res.reason}`);
this.clearSessions();
break;
}
}

for (const token of this._tokens) {
/* __GDPR__
"login" : {
"owner": "TylerLeonhardt",
"comment": "Used to determine the usage of the Microsoft Auth Provider.",
"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." }
"accountType": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what account types are being used." }
}
*/
this._telemetryReporter.sendTelemetryEvent('account', {
// Get rid of guids from telemetry.
scopes: JSON.stringify(token.scope.replace(/[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/i, '{guid}').split(' ')),
accountType: token.account.type
});
}
}

//#region session operations
Expand Down Expand Up @@ -504,7 +531,8 @@ export class AzureActiveDirectoryService {
sessionId: existingId || `${id}/${randomUUID()}`,
account: {
label,
id
id,
type: claims.tid === MSA_TID || claims.tid === MSA_PASSTHRU_TID ? MicrosoftAccountType.MSA : MicrosoftAccountType.AAD
}
};
}
Expand Down Expand Up @@ -911,25 +939,4 @@ export class AzureActiveDirectoryService {
}

//#endregion

//#region static methods

private static getCallbackEnvironment(callbackUri: vscode.Uri): string {
if (callbackUri.scheme !== 'https' && callbackUri.scheme !== 'http') {
return callbackUri.scheme;
}

switch (callbackUri.authority) {
case 'online.visualstudio.com':
return 'vso';
case 'online-ppe.core.vsengsaas.visualstudio.com':
return 'vsoppe';
case 'online.dev.core.vsengsaas.visualstudio.com':
return 'vsodev';
default:
return callbackUri.authority;
}
}

//#endregion
}
7 changes: 4 additions & 3 deletions extensions/microsoft-authentication/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ async function initMicrosoftSovereignCloudAuthProvider(context: vscode.Extension
context,
uriHandler,
tokenStorage,
telemetryReporter,
settingValue);
await aadService.initialize();

Expand Down Expand Up @@ -94,20 +95,20 @@ async function initMicrosoftSovereignCloudAuthProvider(context: vscode.Extension
}

export async function activate(context: vscode.ExtensionContext) {
const { name, version, aiKey } = context.extension.packageJSON as { name: string; version: string; aiKey: string };
const aiKey: string = context.extension.packageJSON.aiKey;
const telemetryReporter = new TelemetryReporter(aiKey);

const uriHandler = new UriEventHandler();
context.subscriptions.push(uriHandler);
context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));

const betterSecretStorage = new BetterTokenStorage<IStoredSession>('microsoft.login.keylist', context);

const loginService = new AzureActiveDirectoryService(
vscode.window.createOutputChannel(vscode.l10n.t('Microsoft Authentication'), { log: true }),
context,
uriHandler,
betterSecretStorage);
betterSecretStorage,
telemetryReporter);
await loginService.initialize();

context.subscriptions.push(vscode.authentication.registerAuthenticationProvider('microsoft', 'Microsoft', {
Expand Down