Path: blob/main/extensions/copilot/src/platform/authentication/vscode-node/authenticationService.ts
13401 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { authentication, AuthenticationGetSessionOptions, AuthenticationSession } from 'vscode';6import { TaskSingler } from '../../../util/common/taskSingler';7import { AuthProviderId, IConfigurationService } from '../../configuration/common/configurationService';8import { IDomainService } from '../../endpoint/common/domainService';9import { ILogService } from '../../log/common/logService';10import { authProviderId, BaseAuthenticationService, StrictAuthenticationPresentationOptions } from '../common/authentication';11import { ICopilotTokenManager } from '../common/copilotTokenManager';12import { ICopilotTokenStore } from '../common/copilotTokenStore';13import { getAlignedSession, getAnyAuthSession } from './session';1415export class AuthenticationService extends BaseAuthenticationService {16private _taskSingler = new TaskSingler<AuthenticationSession | undefined>();1718constructor(19@IConfigurationService configurationService: IConfigurationService,20@IDomainService private readonly _domainService: IDomainService,21@ILogService logService: ILogService,22@ICopilotTokenStore tokenStore: ICopilotTokenStore,23@ICopilotTokenManager tokenManager: ICopilotTokenManager24) {25super(logService, tokenStore, tokenManager, configurationService);26this._register(authentication.onDidChangeSessions((e) => {27if (e.provider.id === authProviderId(configurationService) || e.provider.id === AuthProviderId.Microsoft) {28this._logService.debug('Handling onDidChangeSession.');29void this._handleAuthChangeEvent();30}31}));32this._register(this._domainService.onDidChangeDomains((e) => {33if (e.dotcomUrlChanged) {34this._logService.debug('Handling onDidChangeDomains.');35void this._handleAuthChangeEvent();36}37}));3839void this._handleAuthChangeEvent();40}4142override async getGitHubSession(kind: 'permissive' | 'any', options: AuthenticationGetSessionOptions & { createIfNone: StrictAuthenticationPresentationOptions }): Promise<AuthenticationSession>;43override async getGitHubSession(kind: 'permissive' | 'any', options: AuthenticationGetSessionOptions & { forceNewSession: StrictAuthenticationPresentationOptions }): Promise<AuthenticationSession>;44override async getGitHubSession(kind: 'permissive' | 'any', options: AuthenticationGetSessionOptions): Promise<AuthenticationSession | undefined> {45if (kind === 'permissive') {46const func = () => getAlignedSession(this._configurationService, options);47// If we are doing an interactive flow, don't use the singler so that we don't get hung up on the user's choice48const session = options?.createIfNone || options?.forceNewSession ? await func() : await this._taskSingler.getOrCreate('permissive', func);49this._permissiveGitHubSession = session;50return session;51} else {52const func = () => getAnyAuthSession(this._configurationService, options);53// If we are doing an interactive flow, don't use the singler so that we don't get hung up on the user's choice54const session = options?.createIfNone || options?.forceNewSession ? await func() : await this._taskSingler.getOrCreate('any', func);55this._anyGitHubSession = session;56return session;57}58}5960protected async getAnyAdoSession(options?: AuthenticationGetSessionOptions): Promise<AuthenticationSession | undefined> {61const adoAuthProviderId = 'microsoft';62const adoScopes = ['499b84ac-1321-427f-aa17-267ca6975798/.default', 'offline_access'];63const func = async () => await authentication.getSession(adoAuthProviderId, adoScopes, options);64// If we are doing an interactive flow, don't use the singler so that we don't get hung up on the user's choice65const session = options?.createIfNone || options?.forceNewSession ? await func() : await this._taskSingler.getOrCreate('ado', func);66this._anyAdoSession = session;67return session;68}6970async getAdoAccessTokenBase64(options?: AuthenticationGetSessionOptions): Promise<string | undefined> {71const session = await this.getAnyAdoSession(options);72return session ? Buffer.from(`PAT:${session.accessToken}`, 'utf8').toString('base64') : undefined;73}74}757677