Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/platform/authentication/vscode-node/authenticationService.ts
13401 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
6
import { authentication, AuthenticationGetSessionOptions, AuthenticationSession } from 'vscode';
7
import { TaskSingler } from '../../../util/common/taskSingler';
8
import { AuthProviderId, IConfigurationService } from '../../configuration/common/configurationService';
9
import { IDomainService } from '../../endpoint/common/domainService';
10
import { ILogService } from '../../log/common/logService';
11
import { authProviderId, BaseAuthenticationService, StrictAuthenticationPresentationOptions } from '../common/authentication';
12
import { ICopilotTokenManager } from '../common/copilotTokenManager';
13
import { ICopilotTokenStore } from '../common/copilotTokenStore';
14
import { getAlignedSession, getAnyAuthSession } from './session';
15
16
export class AuthenticationService extends BaseAuthenticationService {
17
private _taskSingler = new TaskSingler<AuthenticationSession | undefined>();
18
19
constructor(
20
@IConfigurationService configurationService: IConfigurationService,
21
@IDomainService private readonly _domainService: IDomainService,
22
@ILogService logService: ILogService,
23
@ICopilotTokenStore tokenStore: ICopilotTokenStore,
24
@ICopilotTokenManager tokenManager: ICopilotTokenManager
25
) {
26
super(logService, tokenStore, tokenManager, configurationService);
27
this._register(authentication.onDidChangeSessions((e) => {
28
if (e.provider.id === authProviderId(configurationService) || e.provider.id === AuthProviderId.Microsoft) {
29
this._logService.debug('Handling onDidChangeSession.');
30
void this._handleAuthChangeEvent();
31
}
32
}));
33
this._register(this._domainService.onDidChangeDomains((e) => {
34
if (e.dotcomUrlChanged) {
35
this._logService.debug('Handling onDidChangeDomains.');
36
void this._handleAuthChangeEvent();
37
}
38
}));
39
40
void this._handleAuthChangeEvent();
41
}
42
43
override async getGitHubSession(kind: 'permissive' | 'any', options: AuthenticationGetSessionOptions & { createIfNone: StrictAuthenticationPresentationOptions }): Promise<AuthenticationSession>;
44
override async getGitHubSession(kind: 'permissive' | 'any', options: AuthenticationGetSessionOptions & { forceNewSession: StrictAuthenticationPresentationOptions }): Promise<AuthenticationSession>;
45
override async getGitHubSession(kind: 'permissive' | 'any', options: AuthenticationGetSessionOptions): Promise<AuthenticationSession | undefined> {
46
if (kind === 'permissive') {
47
const func = () => getAlignedSession(this._configurationService, options);
48
// If we are doing an interactive flow, don't use the singler so that we don't get hung up on the user's choice
49
const session = options?.createIfNone || options?.forceNewSession ? await func() : await this._taskSingler.getOrCreate('permissive', func);
50
this._permissiveGitHubSession = session;
51
return session;
52
} else {
53
const func = () => getAnyAuthSession(this._configurationService, options);
54
// If we are doing an interactive flow, don't use the singler so that we don't get hung up on the user's choice
55
const session = options?.createIfNone || options?.forceNewSession ? await func() : await this._taskSingler.getOrCreate('any', func);
56
this._anyGitHubSession = session;
57
return session;
58
}
59
}
60
61
protected async getAnyAdoSession(options?: AuthenticationGetSessionOptions): Promise<AuthenticationSession | undefined> {
62
const adoAuthProviderId = 'microsoft';
63
const adoScopes = ['499b84ac-1321-427f-aa17-267ca6975798/.default', 'offline_access'];
64
const func = async () => await authentication.getSession(adoAuthProviderId, adoScopes, options);
65
// If we are doing an interactive flow, don't use the singler so that we don't get hung up on the user's choice
66
const session = options?.createIfNone || options?.forceNewSession ? await func() : await this._taskSingler.getOrCreate('ado', func);
67
this._anyAdoSession = session;
68
return session;
69
}
70
71
async getAdoAccessTokenBase64(options?: AuthenticationGetSessionOptions): Promise<string | undefined> {
72
const session = await this.getAnyAdoSession(options);
73
return session ? Buffer.from(`PAT:${session.accessToken}`, 'utf8').toString('base64') : undefined;
74
}
75
}
76
77