Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/authentication/vscode-node/authentication.contribution.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
import { commands, window } from 'vscode';
6
import { IAuthenticationService } from '../../../platform/authentication/common/authentication';
7
import { IAuthenticationChatUpgradeService } from '../../../platform/authentication/common/authenticationUpgrade';
8
import { IVSCodeExtensionContext } from '../../../platform/extContext/common/extensionContext';
9
import { ILogService } from '../../../platform/log/common/logService';
10
import { Event } from '../../../util/vs/base/common/event';
11
import { Disposable } from '../../../util/vs/base/common/lifecycle';
12
import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';
13
14
/**
15
* The main entry point for the authentication contribution.
16
*/
17
export class AuthenticationContrib extends Disposable {
18
constructor(@IInstantiationService private readonly instantiationService: IInstantiationService) {
19
super();
20
this.askToUpgradeAuthPermissions();
21
}
22
private async askToUpgradeAuthPermissions() {
23
const authUpgradeAsk = this._register(this.instantiationService.createInstance(AuthUpgradeAsk));
24
await authUpgradeAsk.run();
25
}
26
}
27
28
/**
29
* This contribution ensures we have a token that is good enough for making API calls for current workspace.
30
*/
31
class AuthUpgradeAsk extends Disposable {
32
private static readonly AUTH_UPGRADE_ASK_KEY = 'copilot.shownPermissiveTokenModal';
33
34
constructor(
35
@IAuthenticationService private readonly _authenticationService: IAuthenticationService,
36
@ILogService private readonly _logService: ILogService,
37
@IVSCodeExtensionContext private readonly _extensionContext: IVSCodeExtensionContext,
38
@IAuthenticationChatUpgradeService private readonly _authenticationChatUpgradeService: IAuthenticationChatUpgradeService,
39
) {
40
super();
41
this._register(commands.registerCommand('github.copilot.chat.triggerPermissiveSignIn', async () => {
42
await this._authenticationChatUpgradeService.showPermissiveSessionModal(true);
43
}));
44
}
45
46
async run() {
47
await this.waitForChatEnabled();
48
this.registerListeners();
49
await this.showPrompt();
50
}
51
52
private async waitForChatEnabled() {
53
try {
54
await this._authenticationService.getCopilotToken();
55
} catch (error) {
56
// likely due to the user canceling the auth flow
57
this._logService.error(error, 'Failed to get copilot token');
58
}
59
60
await Event.toPromise(
61
Event.filter(
62
this._authenticationService.onDidAuthenticationChange,
63
() => this._authenticationService.copilotToken !== undefined
64
)
65
);
66
}
67
68
private registerListeners() {
69
this._register(this._authenticationService.onDidAuthenticationChange(async () => {
70
if (this._authenticationService.permissiveGitHubSession) {
71
return;
72
}
73
if (!this._authenticationService.anyGitHubSession) {
74
// We signed out, so we should show the prompt again
75
this._extensionContext.globalState.update(AuthUpgradeAsk.AUTH_UPGRADE_ASK_KEY, false);
76
return;
77
}
78
if (window.state.focused) {
79
await this.showPrompt();
80
} else {
81
// Wait for the window to get focus before trying to show the prompt
82
const disposable = window.onDidChangeWindowState(async (e) => {
83
if (e.focused) {
84
disposable.dispose();
85
await this.showPrompt();
86
}
87
});
88
}
89
}));
90
}
91
92
private async showPrompt() {
93
if (
94
// Already asked in a previous session
95
this._extensionContext.globalState.get(AuthUpgradeAsk.AUTH_UPGRADE_ASK_KEY, false)
96
// Some other criteria for not showing the prompt
97
|| !(await this._authenticationChatUpgradeService.shouldRequestPermissiveSessionUpgrade())
98
) {
99
return;
100
}
101
if (await this._authenticationChatUpgradeService.showPermissiveSessionModal()) {
102
this._logService.debug('Got permissive GitHub token');
103
} else {
104
this._logService.debug('Did not get permissive GitHub token');
105
}
106
this._extensionContext.globalState.update(AuthUpgradeAsk.AUTH_UPGRADE_ASK_KEY, true);
107
}
108
}
109
110