Skip to content

Commit 852df30

Browse files
author
Rachel Macfarlane
committed
Revert "Issue distinct sessions per extension, remove session when extension is removed from trusted list"
This reverts commit 85119af.
1 parent 20f1853 commit 852df30

8 files changed

Lines changed: 18 additions & 97 deletions

File tree

extensions/github-authentication/src/github.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as vscode from 'vscode';
7-
import * as uuid from 'uuid';
87
import { keychain } from './common/keychain';
98
import { GitHubServer } from './githubServer';
109
import Logger from './common/logger';
@@ -123,7 +122,7 @@ export class GitHubAuthenticationProvider {
123122
private async tokenToSession(token: string, scopes: string[]): Promise<vscode.AuthenticationSession> {
124123
const userInfo = await this._githubServer.getUserInfo(token);
125124
return {
126-
id: uuid(),
125+
id: userInfo.id,
127126
getAccessToken: () => Promise.resolve(token),
128127
accountName: userInfo.accountName,
129128
scopes: scopes

extensions/vscode-account/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,9 @@
3838
"typescript": "^3.7.4",
3939
"tslint": "^5.12.1",
4040
"@types/node": "^10.12.21",
41-
"@types/keytar": "^4.0.1",
42-
"@types/uuid": "^3.4.6"
41+
"@types/keytar": "^4.0.1"
4342
},
4443
"dependencies": {
45-
"uuid": "^3.3.3",
4644
"vscode-nls": "^4.1.1"
4745
}
4846
}

extensions/vscode-account/src/AADHelper.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import * as crypto from 'crypto';
77
import * as https from 'https';
88
import * as querystring from 'querystring';
99
import * as vscode from 'vscode';
10-
import * as uuid from 'uuid';
1110
import { createServer, startServer } from './authServer';
1211
import { keychain } from './keychain';
1312
import Logger from './logger';
@@ -408,7 +407,7 @@ export class AzureActiveDirectoryService {
408407
accessToken: json.access_token,
409408
refreshToken: json.refresh_token,
410409
scope,
411-
sessionId: `${claims.tid}/${(claims.oid || (claims.altsecid || '' + claims.ipd || ''))}/${uuid()}`,
410+
sessionId: `${claims.tid}/${(claims.oid || (claims.altsecid || '' + claims.ipd || ''))}/${scope}`,
412411
accountName: claims.email || claims.unique_name || 'user@example.com'
413412
};
414413
}

extensions/vscode-account/yarn.lock

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@
3030
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.13.tgz#ccebcdb990bd6139cd16e84c39dc2fb1023ca90c"
3131
integrity sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==
3232

33-
"@types/uuid@^3.4.6":
34-
version "3.4.8"
35-
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.8.tgz#4ba887fcef88bd9a7515ca2de336d691e3e18318"
36-
integrity sha512-zHWce3allXWSmRx6/AGXKCtSOA7JjeWd2L3t4aHfysNk8mouQnWCocveaT7a4IEIlPVHp81jzlnknqTgCjCLXA==
37-
3833
ansi-regex@^2.0.0:
3934
version "2.1.1"
4035
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@@ -640,11 +635,6 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1:
640635
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
641636
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
642637

643-
uuid@^3.3.3:
644-
version "3.4.0"
645-
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
646-
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
647-
648638
vscode-nls@^4.1.1:
649639
version "4.1.1"
650640
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c"

src/vs/workbench/api/browser/mainThreadAuthentication.ts

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const BUILT_IN_AUTH_DEPENDENTS: AuthDependent[] = [
3535
interface AllowedExtension {
3636
id: string;
3737
name: string;
38-
sessionIds?: string[];
3938
}
4039

4140
function readAllowedExtensions(storageService: IStorageService, providerId: string, accountName: string): AllowedExtension[] {
@@ -86,16 +85,6 @@ export class MainThreadAuthenticationProvider extends Disposable {
8685
quickPick.onDidAccept(() => {
8786
const updatedAllowedList = quickPick.selectedItems.map(item => item.extension);
8887
storageService.store(`${this.id}-${accountName}`, JSON.stringify(updatedAllowedList), StorageScope.GLOBAL);
89-
90-
// Remove sessions of untrusted extensions
91-
const deselectedItems = items.filter(item => !quickPick.selectedItems.includes(item));
92-
deselectedItems.forEach(item => {
93-
const extensionData = allowedExtensions.find(extension => item.extension.id === extension.id);
94-
extensionData?.sessionIds?.forEach(sessionId => {
95-
this.logout(sessionId);
96-
});
97-
});
98-
9988
quickPick.dispose();
10089
});
10190

@@ -286,19 +275,9 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
286275
this.authenticationService.sessionsUpdate(id, event);
287276
}
288277

289-
async $getSessionsPrompt(providerId: string, accountName: string, sessionId: string, providerName: string, extensionId: string, extensionName: string): Promise<boolean> {
290-
const allowList = readAllowedExtensions(this.storageService, providerId, accountName);
291-
const extensionData = allowList.find(extension => extension.id === extensionId);
292-
if (extensionData) {
293-
if (!extensionData.sessionIds) {
294-
extensionData.sessionIds = [];
295-
}
296-
297-
if (!extensionData.sessionIds.find(id => id === sessionId)) {
298-
extensionData.sessionIds.push(sessionId);
299-
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
300-
}
301-
278+
async $getSessionsPrompt(providerId: string, accountName: string, providerName: string, extensionId: string, extensionName: string): Promise<boolean> {
279+
let allowList = readAllowedExtensions(this.storageService, providerId, accountName);
280+
if (allowList.some(extension => extension.id === extensionId)) {
302281
return true;
303282
}
304283

@@ -313,7 +292,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
313292

314293
const allow = choice === 1;
315294
if (allow) {
316-
allowList.push({ id: extensionId, name: extensionName, sessionIds: [sessionId] });
295+
allowList = allowList.concat({ id: extensionId, name: extensionName });
317296
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
318297
}
319298

@@ -334,10 +313,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
334313
}
335314

336315
async $setTrustedExtension(providerId: string, accountName: string, extensionId: string, extensionName: string): Promise<void> {
337-
const allowList = readAllowedExtensions(this.storageService, providerId, accountName);
338-
if (!allowList.find(allowed => allowed.id === extensionId)) {
339-
allowList.push({ id: extensionId, name: extensionName, sessionIds: [] });
340-
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
341-
}
316+
const allowList = readAllowedExtensions(this.storageService, providerId, accountName).concat({ id: extensionId, name: extensionName });
317+
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
342318
}
343319
}

src/vs/workbench/api/common/extHost.api.impl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
133133
const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol));
134134
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors));
135135
const extHostTheming = rpcProtocol.set(ExtHostContext.ExtHostTheming, new ExtHostTheming(rpcProtocol));
136-
const extHostAuthentication = rpcProtocol.set(ExtHostContext.ExtHostAuthentication, new ExtHostAuthentication(rpcProtocol, extHostStorage));
136+
const extHostAuthentication = rpcProtocol.set(ExtHostContext.ExtHostAuthentication, new ExtHostAuthentication(rpcProtocol));
137137
const extHostTimeline = rpcProtocol.set(ExtHostContext.ExtHostTimeline, new ExtHostTimeline(rpcProtocol, extHostCommands));
138138
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment, extHostWorkspace, extHostLogService, extHostApiDeprecation, extHostDocuments));
139139

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ export interface MainThreadAuthenticationShape extends IDisposable {
158158
$registerAuthenticationProvider(id: string, displayName: string): void;
159159
$unregisterAuthenticationProvider(id: string): void;
160160
$onDidChangeSessions(providerId: string, event: modes.AuthenticationSessionsChangeEvent): void;
161-
$getSessionsPrompt(providerId: string, accountName: string, sessionId: string, providerName: string, extensionId: string, extensionName: string): Promise<boolean>;
161+
$getSessionsPrompt(providerId: string, accountName: string, providerName: string, extensionId: string, extensionName: string): Promise<boolean>;
162162
$loginPrompt(providerName: string, extensionName: string): Promise<boolean>;
163163
$setTrustedExtension(providerId: string, accountName: string, extensionId: string, extensionName: string): Promise<void>;
164164
}

src/vs/workbench/api/common/extHostAuthentication.ts

Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { Emitter, Event } from 'vs/base/common/event';
99
import { IMainContext, MainContext, MainThreadAuthenticationShape, ExtHostAuthenticationShape } from 'vs/workbench/api/common/extHost.protocol';
1010
import { Disposable } from 'vs/workbench/api/common/extHostTypes';
1111
import { IExtensionDescription, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
12-
import { IExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
1312

1413
export class ExtHostAuthentication implements ExtHostAuthenticationShape {
1514
private _proxy: MainThreadAuthenticationShape;
@@ -21,8 +20,7 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
2120
private _onDidChangeSessions = new Emitter<{ [providerId: string]: vscode.AuthenticationSessionsChangeEvent }>();
2221
readonly onDidChangeSessions: Event<{ [providerId: string]: vscode.AuthenticationSessionsChangeEvent }> = this._onDidChangeSessions.event;
2322

24-
constructor(mainContext: IMainContext,
25-
@IExtHostStorage private readonly storageService: IExtHostStorage) {
23+
constructor(mainContext: IMainContext) {
2624
this._proxy = mainContext.getProxy(MainContext.MainThreadAuthentication);
2725
}
2826

@@ -35,34 +33,15 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
3533
return ids;
3634
}
3735

38-
private async hasNotBeenReadByOtherExtension(providerId: string, session: vscode.AuthenticationSession, extensionId: string): Promise<boolean> {
39-
const readerId = await this.storageService.getValue(true, `${providerId}-${session.accountName}-${session.id}`);
40-
if (!readerId) {
41-
await this.storageService.setValue(true, `${providerId}-${session.accountName}-${session.id}`, extensionId as any);
42-
return true;
43-
}
44-
45-
return readerId === extensionId;
46-
}
47-
48-
private async isMatchingSession(session: vscode.AuthenticationSession, scopes: string, providerId: string, extensionId: string): Promise<boolean> {
49-
return session.scopes.sort().join(' ') === scopes && (await this.hasNotBeenReadByOtherExtension(providerId, session, extensionId));
50-
}
51-
5236
async getSessions(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<readonly vscode.AuthenticationSession[]> {
5337
const provider = this._authenticationProviders.get(providerId);
5438
if (!provider) {
5539
throw new Error(`No authentication provider with id '${providerId}' is currently registered.`);
5640
}
5741

58-
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
5942
const orderedScopes = scopes.sort().join(' ');
60-
61-
const sessions = await provider.getSessions();
62-
const filteredSessions = await Promise.all(sessions.map(session => this.isMatchingSession(session, orderedScopes, providerId, extensionId)));
63-
64-
return sessions
65-
.filter((_, i) => { return filteredSessions[i]; })
43+
return (await provider.getSessions())
44+
.filter(session => session.scopes.sort().join(' ') === orderedScopes)
6645
.map(session => {
6746
return {
6847
id: session.id,
@@ -72,9 +51,8 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
7251
const isAllowed = await this._proxy.$getSessionsPrompt(
7352
provider.id,
7453
session.accountName,
75-
session.id,
7654
provider.displayName,
77-
extensionId,
55+
ExtensionIdentifier.toKey(requestingExtension.identifier),
7856
requestingExtension.displayName || requestingExtension.name);
7957

8058
if (!isAllowed) {
@@ -99,28 +77,9 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
9977
throw new Error('User did not consent to login.');
10078
}
10179

102-
const session = await provider.login(scopes);
103-
await this._proxy.$setTrustedExtension(provider.id, session.accountName, ExtensionIdentifier.toKey(requestingExtension.identifier), extensionName);
104-
return {
105-
id: session.id,
106-
accountName: session.accountName,
107-
scopes: session.scopes,
108-
getAccessToken: async () => {
109-
const isAllowed = await this._proxy.$getSessionsPrompt(
110-
provider.id,
111-
session.accountName,
112-
session.id,
113-
provider.displayName,
114-
ExtensionIdentifier.toKey(requestingExtension.identifier),
115-
requestingExtension.displayName || requestingExtension.name);
116-
117-
if (!isAllowed) {
118-
throw new Error('User did not consent to token access.');
119-
}
120-
121-
return session.getAccessToken();
122-
}
123-
};
80+
const newSession = await provider.login(scopes);
81+
await this._proxy.$setTrustedExtension(provider.id, newSession.accountName, ExtensionIdentifier.toKey(requestingExtension.identifier), extensionName);
82+
return newSession;
12483
}
12584

12685
registerAuthenticationProvider(provider: vscode.AuthenticationProvider): vscode.Disposable {

0 commit comments

Comments
 (0)