mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-23 11:49:38 +00:00
Introduce auth-provider specific props & use it for social sign in for GitHub (#251649)
ref https://github.com/microsoft/vscode/issues/251648 NOTE: the server side is not quite ready. It doesn't redirect back to VS Code properly, but this should be good to go whenever that is.
This commit is contained in:
committed by
GitHub
parent
480485f0d0
commit
2fabac413d
@@ -18,7 +18,8 @@
|
|||||||
"workspace"
|
"workspace"
|
||||||
],
|
],
|
||||||
"enabledApiProposals": [
|
"enabledApiProposals": [
|
||||||
"authIssuers"
|
"authIssuers",
|
||||||
|
"authProviderSpecific"
|
||||||
],
|
],
|
||||||
"activationEvents": [],
|
"activationEvents": [],
|
||||||
"capabilities": {
|
"capabilities": {
|
||||||
|
|||||||
@@ -60,15 +60,46 @@ export interface IFlowQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IFlowTriggerOptions {
|
interface IFlowTriggerOptions {
|
||||||
|
/**
|
||||||
|
* The scopes to request for the OAuth flow.
|
||||||
|
*/
|
||||||
scopes: string;
|
scopes: string;
|
||||||
|
/**
|
||||||
|
* The base URI for the flow. This is used to determine which GitHub instance to authenticate against.
|
||||||
|
*/
|
||||||
baseUri: Uri;
|
baseUri: Uri;
|
||||||
logger: Log;
|
/**
|
||||||
|
* The specific auth provider to use for the flow.
|
||||||
|
*/
|
||||||
|
signInProvider?: GitHubSocialSignInProvider;
|
||||||
|
/**
|
||||||
|
* The Uri that the OAuth flow will redirect to. (i.e. vscode.dev/redirect)
|
||||||
|
*/
|
||||||
redirectUri: Uri;
|
redirectUri: Uri;
|
||||||
nonce: string;
|
/**
|
||||||
|
* The Uri to redirect to after redirecting to the redirect Uri. (i.e. vscode://....)
|
||||||
|
*/
|
||||||
callbackUri: Uri;
|
callbackUri: Uri;
|
||||||
uriHandler: UriEventHandler;
|
/**
|
||||||
|
* The enterprise URI for the flow, if applicable.
|
||||||
|
*/
|
||||||
enterpriseUri?: Uri;
|
enterpriseUri?: Uri;
|
||||||
|
/**
|
||||||
|
* The existing login which will be used to pre-fill the login prompt.
|
||||||
|
*/
|
||||||
existingLogin?: string;
|
existingLogin?: string;
|
||||||
|
/**
|
||||||
|
* The nonce for this particular flow. This is used to prevent replay attacks.
|
||||||
|
*/
|
||||||
|
nonce: string;
|
||||||
|
/**
|
||||||
|
* The instance of the Uri Handler for this extension
|
||||||
|
*/
|
||||||
|
uriHandler: UriEventHandler;
|
||||||
|
/**
|
||||||
|
* The logger to use for this flow.
|
||||||
|
*/
|
||||||
|
logger: Log;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IFlow {
|
interface IFlow {
|
||||||
@@ -143,12 +174,13 @@ class UrlHandlerFlow implements IFlow {
|
|||||||
scopes,
|
scopes,
|
||||||
baseUri,
|
baseUri,
|
||||||
redirectUri,
|
redirectUri,
|
||||||
logger,
|
|
||||||
nonce,
|
|
||||||
callbackUri,
|
callbackUri,
|
||||||
uriHandler,
|
|
||||||
enterpriseUri,
|
enterpriseUri,
|
||||||
existingLogin
|
nonce,
|
||||||
|
signInProvider: authProvider,
|
||||||
|
uriHandler,
|
||||||
|
existingLogin,
|
||||||
|
logger,
|
||||||
}: IFlowTriggerOptions): Promise<string> {
|
}: IFlowTriggerOptions): Promise<string> {
|
||||||
logger.info(`Trying without local server... (${scopes})`);
|
logger.info(`Trying without local server... (${scopes})`);
|
||||||
return await window.withProgress<string>({
|
return await window.withProgress<string>({
|
||||||
@@ -177,7 +209,7 @@ class UrlHandlerFlow implements IFlow {
|
|||||||
// The extra toString, parse is apparently needed for env.openExternal
|
// The extra toString, parse is apparently needed for env.openExternal
|
||||||
// to open the correct URL.
|
// to open the correct URL.
|
||||||
const uri = Uri.parse(baseUri.with({
|
const uri = Uri.parse(baseUri.with({
|
||||||
path: '/login/oauth/authorize',
|
path: getAuthorizeUrlPath(authProvider),
|
||||||
query: searchParams.toString()
|
query: searchParams.toString()
|
||||||
}).toString(true));
|
}).toString(true));
|
||||||
await env.openExternal(uri);
|
await env.openExternal(uri);
|
||||||
@@ -219,10 +251,11 @@ class LocalServerFlow implements IFlow {
|
|||||||
scopes,
|
scopes,
|
||||||
baseUri,
|
baseUri,
|
||||||
redirectUri,
|
redirectUri,
|
||||||
logger,
|
|
||||||
callbackUri,
|
callbackUri,
|
||||||
enterpriseUri,
|
enterpriseUri,
|
||||||
existingLogin
|
signInProvider: authProvider,
|
||||||
|
existingLogin,
|
||||||
|
logger
|
||||||
}: IFlowTriggerOptions): Promise<string> {
|
}: IFlowTriggerOptions): Promise<string> {
|
||||||
logger.info(`Trying with local server... (${scopes})`);
|
logger.info(`Trying with local server... (${scopes})`);
|
||||||
return await window.withProgress<string>({
|
return await window.withProgress<string>({
|
||||||
@@ -246,7 +279,7 @@ class LocalServerFlow implements IFlow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const loginUrl = baseUri.with({
|
const loginUrl = baseUri.with({
|
||||||
path: '/login/oauth/authorize',
|
path: getAuthorizeUrlPath(authProvider),
|
||||||
query: searchParams.toString()
|
query: searchParams.toString()
|
||||||
});
|
});
|
||||||
const server = new LoopbackAuthServer(path.join(__dirname, '../media'), loginUrl.toString(true), callbackUri.toString(true));
|
const server = new LoopbackAuthServer(path.join(__dirname, '../media'), loginUrl.toString(true), callbackUri.toString(true));
|
||||||
@@ -520,3 +553,24 @@ export function getFlows(query: IFlowQuery) {
|
|||||||
return useFlow;
|
return useFlow;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Social authentication providers for GitHub
|
||||||
|
*/
|
||||||
|
export const enum GitHubSocialSignInProvider {
|
||||||
|
Google = 'google',
|
||||||
|
// Apple = 'apple',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isSocialSignInProvider(provider: unknown): provider is GitHubSocialSignInProvider {
|
||||||
|
return provider === GitHubSocialSignInProvider.Google; // || provider === GitHubSocialSignInProvider.Apple;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAuthorizeUrlPath(provider: GitHubSocialSignInProvider | undefined): string {
|
||||||
|
switch (provider) {
|
||||||
|
case GitHubSocialSignInProvider.Google:
|
||||||
|
// case GitHubSocialSignInProvider.Apple:
|
||||||
|
return `/sessions/social/${provider}/initiate`;
|
||||||
|
}
|
||||||
|
return '/login/oauth/authorize';
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { ExperimentationTelemetry } from './common/experimentationService';
|
|||||||
import { Log } from './common/logger';
|
import { Log } from './common/logger';
|
||||||
import { crypto } from './node/crypto';
|
import { crypto } from './node/crypto';
|
||||||
import { TIMED_OUT_ERROR, USER_CANCELLATION_ERROR } from './common/errors';
|
import { TIMED_OUT_ERROR, USER_CANCELLATION_ERROR } from './common/errors';
|
||||||
|
import { GitHubSocialSignInProvider, isSocialSignInProvider } from './flows';
|
||||||
|
|
||||||
interface SessionData {
|
interface SessionData {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -31,6 +32,20 @@ export enum AuthProviderType {
|
|||||||
githubEnterprise = 'github-enterprise'
|
githubEnterprise = 'github-enterprise'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface GitHubAuthenticationProviderOptions extends vscode.AuthenticationProviderSessionOptions {
|
||||||
|
/**
|
||||||
|
* This is specific to GitHub and is used to determine which social sign-in provider to use.
|
||||||
|
* If not provided, the default (GitHub) is used which shows all options.
|
||||||
|
*
|
||||||
|
* Example: If you specify Google, then the sign-in flow will skip the initial page that asks you
|
||||||
|
* to choose how you want to sign in and will directly take you to the Google sign-in page.
|
||||||
|
*
|
||||||
|
* This allows us to show "Continue with Google" buttons in the product, rather than always
|
||||||
|
* leaving it up to the user to choose the social sign-in provider on the sign-in page.
|
||||||
|
*/
|
||||||
|
readonly provider?: GitHubSocialSignInProvider;
|
||||||
|
}
|
||||||
|
|
||||||
export class UriEventHandler extends vscode.EventEmitter<vscode.Uri> implements vscode.UriHandler {
|
export class UriEventHandler extends vscode.EventEmitter<vscode.Uri> implements vscode.UriHandler {
|
||||||
private readonly _pendingNonces = new Map<string, string[]>();
|
private readonly _pendingNonces = new Map<string, string[]>();
|
||||||
private readonly _codeExchangePromises = new Map<string, { promise: Promise<string>; cancel: vscode.EventEmitter<void> }>();
|
private readonly _codeExchangePromises = new Map<string, { promise: Promise<string>; cancel: vscode.EventEmitter<void> }>();
|
||||||
@@ -306,7 +321,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
|
|||||||
this._logger.info(`Stored ${sessions.length} sessions!`);
|
this._logger.info(`Stored ${sessions.length} sessions!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createSession(scopes: string[], options?: vscode.AuthenticationProviderSessionOptions): Promise<vscode.AuthenticationSession> {
|
public async createSession(scopes: string[], options?: GitHubAuthenticationProviderOptions): Promise<vscode.AuthenticationSession> {
|
||||||
try {
|
try {
|
||||||
// For GitHub scope list, order doesn't matter so we use a sorted scope to determine
|
// For GitHub scope list, order doesn't matter so we use a sorted scope to determine
|
||||||
// if we've got a session already.
|
// if we've got a session already.
|
||||||
@@ -325,9 +340,10 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
|
|||||||
|
|
||||||
const sessions = await this._sessionsPromise;
|
const sessions = await this._sessionsPromise;
|
||||||
const loginWith = options?.account?.label;
|
const loginWith = options?.account?.label;
|
||||||
this._logger.info(`Logging in with '${loginWith ? loginWith : 'any'}' account...`);
|
const signInProvider = isSocialSignInProvider(options?.provider) ? options.provider : undefined;
|
||||||
|
this._logger.info(`Logging in with${signInProvider ? ` ${signInProvider}, ` : ''} '${loginWith ? loginWith : 'any'}' account...`);
|
||||||
const scopeString = sortedScopes.join(' ');
|
const scopeString = sortedScopes.join(' ');
|
||||||
const token = await this._githubServer.login(scopeString, loginWith);
|
const token = await this._githubServer.login(scopeString, signInProvider, loginWith);
|
||||||
const session = await this.tokenToSession(token, scopes);
|
const session = await this.tokenToSession(token, scopes);
|
||||||
this.afterSessionLoad(session);
|
this.afterSessionLoad(session);
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { Log } from './common/logger';
|
|||||||
import { isSupportedClient, isSupportedTarget } from './common/env';
|
import { isSupportedClient, isSupportedTarget } from './common/env';
|
||||||
import { crypto } from './node/crypto';
|
import { crypto } from './node/crypto';
|
||||||
import { fetching } from './node/fetch';
|
import { fetching } from './node/fetch';
|
||||||
import { ExtensionHost, GitHubTarget, getFlows } from './flows';
|
import { ExtensionHost, GitHubSocialSignInProvider, GitHubTarget, getFlows } from './flows';
|
||||||
import { CANCELLATION_ERROR, NETWORK_ERROR, USER_CANCELLATION_ERROR } from './common/errors';
|
import { CANCELLATION_ERROR, NETWORK_ERROR, USER_CANCELLATION_ERROR } from './common/errors';
|
||||||
import { Config } from './config';
|
import { Config } from './config';
|
||||||
import { base64Encode } from './node/buffer';
|
import { base64Encode } from './node/buffer';
|
||||||
@@ -19,7 +19,7 @@ const REDIRECT_URL_STABLE = 'https://vscode.dev/redirect';
|
|||||||
const REDIRECT_URL_INSIDERS = 'https://insiders.vscode.dev/redirect';
|
const REDIRECT_URL_INSIDERS = 'https://insiders.vscode.dev/redirect';
|
||||||
|
|
||||||
export interface IGitHubServer {
|
export interface IGitHubServer {
|
||||||
login(scopes: string, existingLogin?: string): Promise<string>;
|
login(scopes: string, signInProvider?: GitHubSocialSignInProvider, existingLogin?: string): Promise<string>;
|
||||||
logout(session: vscode.AuthenticationSession): Promise<void>;
|
logout(session: vscode.AuthenticationSession): Promise<void>;
|
||||||
getUserInfo(token: string): Promise<{ id: string; accountName: string }>;
|
getUserInfo(token: string): Promise<{ id: string; accountName: string }>;
|
||||||
sendAdditionalTelemetryInfo(session: vscode.AuthenticationSession): Promise<void>;
|
sendAdditionalTelemetryInfo(session: vscode.AuthenticationSession): Promise<void>;
|
||||||
@@ -87,7 +87,7 @@ export class GitHubServer implements IGitHubServer {
|
|||||||
return this._isNoCorsEnvironment;
|
return this._isNoCorsEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async login(scopes: string, existingLogin?: string): Promise<string> {
|
public async login(scopes: string, signInProvider?: GitHubSocialSignInProvider, existingLogin?: string): Promise<string> {
|
||||||
this._logger.info(`Logging in for the following scopes: ${scopes}`);
|
this._logger.info(`Logging in for the following scopes: ${scopes}`);
|
||||||
|
|
||||||
// Used for showing a friendlier message to the user when the explicitly cancel a flow.
|
// Used for showing a friendlier message to the user when the explicitly cancel a flow.
|
||||||
@@ -135,6 +135,7 @@ export class GitHubServer implements IGitHubServer {
|
|||||||
scopes,
|
scopes,
|
||||||
callbackUri,
|
callbackUri,
|
||||||
nonce,
|
nonce,
|
||||||
|
signInProvider,
|
||||||
baseUri: this.baseUri,
|
baseUri: this.baseUri,
|
||||||
logger: this._logger,
|
logger: this._logger,
|
||||||
uriHandler: this._uriHandler,
|
uriHandler: this._uriHandler,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"include": [
|
"include": [
|
||||||
"src/**/*",
|
"src/**/*",
|
||||||
"../../src/vscode-dts/vscode.d.ts",
|
"../../src/vscode-dts/vscode.d.ts",
|
||||||
"../../src/vscode-dts/vscode.proposed.authIssuers.d.ts"
|
"../../src/vscode-dts/vscode.proposed.authIssuers.d.ts",
|
||||||
|
"../../src/vscode-dts/vscode.proposed.authProviderSpecific.d.ts"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ const _allApiProposals = {
|
|||||||
authLearnMore: {
|
authLearnMore: {
|
||||||
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authLearnMore.d.ts',
|
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authLearnMore.d.ts',
|
||||||
},
|
},
|
||||||
|
authProviderSpecific: {
|
||||||
|
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authProviderSpecific.d.ts',
|
||||||
|
},
|
||||||
authSession: {
|
authSession: {
|
||||||
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authSession.d.ts',
|
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authSession.d.ts',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import { Disposable, DisposableMap } from '../../../base/common/lifecycle.js';
|
import { Disposable, DisposableMap } from '../../../base/common/lifecycle.js';
|
||||||
import * as nls from '../../../nls.js';
|
import * as nls from '../../../nls.js';
|
||||||
import { extHostNamedCustomer, IExtHostContext } from '../../services/extensions/common/extHostCustomers.js';
|
import { extHostNamedCustomer, IExtHostContext } from '../../services/extensions/common/extHostCustomers.js';
|
||||||
import { IAuthenticationCreateSessionOptions, AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationProvider, IAuthenticationService, IAuthenticationExtensionsService, INTERNAL_AUTH_PROVIDER_PREFIX as INTERNAL_MODEL_AUTH_PROVIDER_PREFIX, AuthenticationSessionAccount, IAuthenticationProviderSessionOptions } from '../../services/authentication/common/authentication.js';
|
import { AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationProvider, IAuthenticationService, IAuthenticationExtensionsService, INTERNAL_AUTH_PROVIDER_PREFIX as INTERNAL_MODEL_AUTH_PROVIDER_PREFIX, AuthenticationSessionAccount, IAuthenticationProviderSessionOptions } from '../../services/authentication/common/authentication.js';
|
||||||
import { ExtHostAuthenticationShape, ExtHostContext, MainContext, MainThreadAuthenticationShape } from '../common/extHost.protocol.js';
|
import { ExtHostAuthenticationShape, ExtHostContext, MainContext, MainThreadAuthenticationShape } from '../common/extHost.protocol.js';
|
||||||
import { IDialogService, IPromptButton } from '../../../platform/dialogs/common/dialogs.js';
|
import { IDialogService, IPromptButton } from '../../../platform/dialogs/common/dialogs.js';
|
||||||
import Severity from '../../../base/common/severity.js';
|
import Severity from '../../../base/common/severity.js';
|
||||||
@@ -64,7 +64,7 @@ export class MainThreadAuthenticationProvider extends Disposable implements IAut
|
|||||||
return this._proxy.$getSessions(this.id, scopes, options);
|
return this._proxy.$getSessions(this.id, scopes, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
createSession(scopes: string[], options: IAuthenticationCreateSessionOptions): Promise<AuthenticationSession> {
|
createSession(scopes: string[], options: IAuthenticationProviderSessionOptions): Promise<AuthenticationSession> {
|
||||||
return this._proxy.$createSession(this.id, scopes, options);
|
return this._proxy.$createSession(this.id, scopes, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescrip
|
|||||||
import { TypeHierarchyItem } from '../../contrib/typeHierarchy/common/typeHierarchy.js';
|
import { TypeHierarchyItem } from '../../contrib/typeHierarchy/common/typeHierarchy.js';
|
||||||
import { RelatedInformationResult, RelatedInformationType } from '../../services/aiRelatedInformation/common/aiRelatedInformation.js';
|
import { RelatedInformationResult, RelatedInformationType } from '../../services/aiRelatedInformation/common/aiRelatedInformation.js';
|
||||||
import { AiSettingsSearchProviderOptions, AiSettingsSearchResult } from '../../services/aiSettingsSearch/common/aiSettingsSearch.js';
|
import { AiSettingsSearchProviderOptions, AiSettingsSearchResult } from '../../services/aiSettingsSearch/common/aiSettingsSearch.js';
|
||||||
import { AuthenticationSession, AuthenticationSessionAccount, AuthenticationSessionsChangeEvent, IAuthenticationCreateSessionOptions, IAuthenticationProviderSessionOptions } from '../../services/authentication/common/authentication.js';
|
import { AuthenticationSession, AuthenticationSessionAccount, AuthenticationSessionsChangeEvent, IAuthenticationCreateSessionOptions, IAuthenticationGetSessionsOptions } from '../../services/authentication/common/authentication.js';
|
||||||
import { EditorGroupColumn } from '../../services/editor/common/editorGroupColumn.js';
|
import { EditorGroupColumn } from '../../services/editor/common/editorGroupColumn.js';
|
||||||
import { IExtensionDescriptionDelta, IStaticWorkspaceData } from '../../services/extensions/common/extensionHostProtocol.js';
|
import { IExtensionDescriptionDelta, IStaticWorkspaceData } from '../../services/extensions/common/extensionHostProtocol.js';
|
||||||
import { IResolveAuthorityResult } from '../../services/extensions/common/extensionHostProxy.js';
|
import { IResolveAuthorityResult } from '../../services/extensions/common/extensionHostProxy.js';
|
||||||
@@ -1981,7 +1981,7 @@ export interface ExtHostLabelServiceShape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ExtHostAuthenticationShape {
|
export interface ExtHostAuthenticationShape {
|
||||||
$getSessions(id: string, scopes: string[] | undefined, options: IAuthenticationProviderSessionOptions): Promise<ReadonlyArray<AuthenticationSession>>;
|
$getSessions(id: string, scopes: string[] | undefined, options: IAuthenticationGetSessionsOptions): Promise<ReadonlyArray<AuthenticationSession>>;
|
||||||
$createSession(id: string, scopes: string[], options: IAuthenticationCreateSessionOptions): Promise<AuthenticationSession>;
|
$createSession(id: string, scopes: string[], options: IAuthenticationCreateSessionOptions): Promise<AuthenticationSession>;
|
||||||
$removeSession(id: string, sessionId: string): Promise<void>;
|
$removeSession(id: string, sessionId: string): Promise<void>;
|
||||||
$onDidChangeAuthenticationSessions(id: string, label: string, extensionIdFilter?: string[]): Promise<void>;
|
$onDidChangeAuthenticationSessions(id: string, label: string, extensionIdFilter?: string[]): Promise<void>;
|
||||||
|
|||||||
@@ -847,6 +847,7 @@ export class ChatEntitlementRequests extends Disposable {
|
|||||||
|
|
||||||
async signIn() {
|
async signIn() {
|
||||||
const providerId = ChatEntitlementRequests.providerId(this.configurationService);
|
const providerId = ChatEntitlementRequests.providerId(this.configurationService);
|
||||||
|
// TODO: Pass in { provider: 'google' } for google sign-in
|
||||||
const session = await this.authenticationService.createSession(providerId, defaultChat.providerScopes[0]);
|
const session = await this.authenticationService.createSession(providerId, defaultChat.providerScopes[0]);
|
||||||
|
|
||||||
this.authenticationExtensionsService.updateAccountPreference(defaultChat.extensionId, providerId, session.account);
|
this.authenticationExtensionsService.updateAccountPreference(defaultChat.extensionId, providerId, session.account);
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ export class AuthenticationService extends Disposable implements IAuthentication
|
|||||||
throw new Error(`The authorization server '${authServerStr}' is not supported by the authentication provider '${id}'.`);
|
throw new Error(`The authorization server '${authServerStr}' is not supported by the authentication provider '${id}'.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return await authProvider.getSessions(scopes, { account: options?.account, authorizationServer: options?.authorizationServer });
|
return await authProvider.getSessions(scopes, { ...options });
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
||||||
}
|
}
|
||||||
@@ -294,10 +294,7 @@ export class AuthenticationService extends Disposable implements IAuthentication
|
|||||||
|
|
||||||
const authProvider = this._authenticationProviders.get(id) || await this.tryActivateProvider(id, !!options?.activateImmediate);
|
const authProvider = this._authenticationProviders.get(id) || await this.tryActivateProvider(id, !!options?.activateImmediate);
|
||||||
if (authProvider) {
|
if (authProvider) {
|
||||||
return await authProvider.createSession(scopes, {
|
return await authProvider.createSession(scopes, { ...options });
|
||||||
account: options?.account,
|
|
||||||
authorizationServer: options?.authorizationServer
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ export interface AuthenticationProviderInformation {
|
|||||||
authorizationServerGlobs?: ReadonlyArray<string>;
|
authorizationServerGlobs?: ReadonlyArray<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for creating an authentication session via the service.
|
||||||
|
*/
|
||||||
export interface IAuthenticationCreateSessionOptions {
|
export interface IAuthenticationCreateSessionOptions {
|
||||||
activateImmediate?: boolean;
|
activateImmediate?: boolean;
|
||||||
/**
|
/**
|
||||||
@@ -50,8 +53,18 @@ export interface IAuthenticationCreateSessionOptions {
|
|||||||
* the provider can use this authorization server, then it is passed down to the auth provider.
|
* the provider can use this authorization server, then it is passed down to the auth provider.
|
||||||
*/
|
*/
|
||||||
authorizationServer?: URI;
|
authorizationServer?: URI;
|
||||||
|
/**
|
||||||
|
* Allows the authentication provider to take in additional parameters.
|
||||||
|
* It is up to the provider to define what these parameters are and handle them.
|
||||||
|
* This is useful for passing in additional information that is specific to the provider
|
||||||
|
* and not part of the standard authentication flow.
|
||||||
|
*/
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for getting authentication sessions via the service.
|
||||||
|
*/
|
||||||
export interface IAuthenticationGetSessionsOptions {
|
export interface IAuthenticationGetSessionsOptions {
|
||||||
/**
|
/**
|
||||||
* The account that is being asked about. If this is passed in, the provider should
|
* The account that is being asked about. If this is passed in, the provider should
|
||||||
@@ -63,6 +76,13 @@ export interface IAuthenticationGetSessionsOptions {
|
|||||||
* the provider can use this authorization server, then it is passed down to the auth provider.
|
* the provider can use this authorization server, then it is passed down to the auth provider.
|
||||||
*/
|
*/
|
||||||
authorizationServer?: URI;
|
authorizationServer?: URI;
|
||||||
|
/**
|
||||||
|
* Allows the authentication provider to take in additional parameters.
|
||||||
|
* It is up to the provider to define what these parameters are and handle them.
|
||||||
|
* This is useful for passing in additional information that is specific to the provider
|
||||||
|
* and not part of the standard authentication flow.
|
||||||
|
*/
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AllowedExtension {
|
export interface AllowedExtension {
|
||||||
@@ -294,6 +314,9 @@ export interface IAuthenticationExtensionsService {
|
|||||||
requestNewSession(providerId: string, scopes: string[], extensionId: string, extensionName: string): Promise<void>;
|
requestNewSession(providerId: string, scopes: string[], extensionId: string, extensionName: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options passed to the authentication provider when asking for sessions.
|
||||||
|
*/
|
||||||
export interface IAuthenticationProviderSessionOptions {
|
export interface IAuthenticationProviderSessionOptions {
|
||||||
/**
|
/**
|
||||||
* The account that is being asked about. If this is passed in, the provider should
|
* The account that is being asked about. If this is passed in, the provider should
|
||||||
@@ -305,6 +328,13 @@ export interface IAuthenticationProviderSessionOptions {
|
|||||||
* attempt to return sessions that are only related to this authorization server.
|
* attempt to return sessions that are only related to this authorization server.
|
||||||
*/
|
*/
|
||||||
authorizationServer?: URI;
|
authorizationServer?: URI;
|
||||||
|
/**
|
||||||
|
* Allows the authentication provider to take in additional parameters.
|
||||||
|
* It is up to the provider to define what these parameters are and handle them.
|
||||||
|
* This is useful for passing in additional information that is specific to the provider
|
||||||
|
* and not part of the standard authentication flow.
|
||||||
|
*/
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
30
src/vscode-dts/vscode.proposed.authProviderSpecific.d.ts
vendored
Normal file
30
src/vscode-dts/vscode.proposed.authProviderSpecific.d.ts
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
declare module 'vscode' {
|
||||||
|
|
||||||
|
// https://github.com/microsoft/vscode/issues/251648
|
||||||
|
|
||||||
|
export interface AuthenticationProviderSessionOptions {
|
||||||
|
/**
|
||||||
|
* Allows the authentication provider to take in additional parameters.
|
||||||
|
* It is up to the provider to define what these parameters are and handle them.
|
||||||
|
* This is useful for passing in additional information that is specific to the provider
|
||||||
|
* and not part of the standard authentication flow.
|
||||||
|
*/
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement this interface if needed via an extension
|
||||||
|
// export interface AuthenticationGetSessionOptions {
|
||||||
|
// /**
|
||||||
|
// * Allows the authentication provider to take in additional parameters.
|
||||||
|
// * It is up to the provider to define what these parameters are and handle them.
|
||||||
|
// * This is useful for passing in additional information that is specific to the provider
|
||||||
|
// * and not part of the standard authentication flow.
|
||||||
|
// */
|
||||||
|
// [key: string]: any;
|
||||||
|
// }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user