Remove old getSessions and login methods from auth provider API
This commit is contained in:
parent
fcbc010e56
commit
629e1d7e16
9 changed files with 32 additions and 141 deletions
|
@ -22,7 +22,7 @@ interface SessionData {
|
|||
}
|
||||
|
||||
export class GitHubAuthenticationProvider {
|
||||
private _sessions: vscode.AuthenticationSession2[] = [];
|
||||
private _sessions: vscode.AuthenticationSession[] = [];
|
||||
private _githubServer = new GitHubServer();
|
||||
|
||||
public async initialize(): Promise<void> {
|
||||
|
@ -37,7 +37,7 @@ export class GitHubAuthenticationProvider {
|
|||
|
||||
private pollForChange() {
|
||||
setTimeout(async () => {
|
||||
let storedSessions: vscode.AuthenticationSession2[];
|
||||
let storedSessions: vscode.AuthenticationSession[];
|
||||
try {
|
||||
storedSessions = await this.readSessions();
|
||||
} catch (e) {
|
||||
|
@ -80,12 +80,12 @@ export class GitHubAuthenticationProvider {
|
|||
}, 1000 * 30);
|
||||
}
|
||||
|
||||
private async readSessions(): Promise<vscode.AuthenticationSession2[]> {
|
||||
private async readSessions(): Promise<vscode.AuthenticationSession[]> {
|
||||
const storedSessions = await keychain.getToken();
|
||||
if (storedSessions) {
|
||||
try {
|
||||
const sessionData: SessionData[] = JSON.parse(storedSessions);
|
||||
const sessionPromises = sessionData.map(async (session: SessionData): Promise<vscode.AuthenticationSession2> => {
|
||||
const sessionPromises = sessionData.map(async (session: SessionData): Promise<vscode.AuthenticationSession> => {
|
||||
const needsUserInfo = !session.account;
|
||||
let userInfo: { id: string, accountName: string };
|
||||
if (needsUserInfo) {
|
||||
|
@ -121,11 +121,11 @@ export class GitHubAuthenticationProvider {
|
|||
await keychain.setToken(JSON.stringify(this._sessions));
|
||||
}
|
||||
|
||||
get sessions(): vscode.AuthenticationSession2[] {
|
||||
get sessions(): vscode.AuthenticationSession[] {
|
||||
return this._sessions;
|
||||
}
|
||||
|
||||
public async login(scopes: string): Promise<vscode.AuthenticationSession2> {
|
||||
public async login(scopes: string): Promise<vscode.AuthenticationSession> {
|
||||
const token = await this._githubServer.login(scopes);
|
||||
const session = await this.tokenToSession(token, scopes.split(' '));
|
||||
await this.setToken(session);
|
||||
|
@ -136,12 +136,12 @@ export class GitHubAuthenticationProvider {
|
|||
this._githubServer.manuallyProvideToken();
|
||||
}
|
||||
|
||||
private async tokenToSession(token: string, scopes: string[]): Promise<vscode.AuthenticationSession2> {
|
||||
private async tokenToSession(token: string, scopes: string[]): Promise<vscode.AuthenticationSession> {
|
||||
const userInfo = await this._githubServer.getUserInfo(token);
|
||||
return new vscode.AuthenticationSession2(uuid(), token, { displayName: userInfo.accountName, id: userInfo.id }, scopes);
|
||||
return new vscode.AuthenticationSession(uuid(), token, { displayName: userInfo.accountName, id: userInfo.id }, scopes);
|
||||
}
|
||||
|
||||
private async setToken(session: vscode.AuthenticationSession2): Promise<void> {
|
||||
private async setToken(session: vscode.AuthenticationSession): Promise<void> {
|
||||
const sessionIndex = this._sessions.findIndex(s => s.id === session.id);
|
||||
if (sessionIndex > -1) {
|
||||
this._sessions.splice(sessionIndex, 1, session);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
'use strict';
|
||||
import {
|
||||
authentication,
|
||||
AuthenticationSession2,
|
||||
AuthenticationSession,
|
||||
CancellationToken,
|
||||
Disposable,
|
||||
Event,
|
||||
|
@ -336,7 +336,7 @@ interface SearchQueryResults {
|
|||
}
|
||||
|
||||
class GitHubApi {
|
||||
constructor(private readonly session: AuthenticationSession2) { }
|
||||
constructor(private readonly session: AuthenticationSession) { }
|
||||
|
||||
private _graphql: typeof graphql | undefined;
|
||||
private get graphql() {
|
||||
|
|
|
@ -27,21 +27,15 @@ function getAgent(url: string | undefined = process.env.HTTPS_PROXY): Agent {
|
|||
const scopes = ['repo', 'workflow'];
|
||||
|
||||
export async function getSession(): Promise<AuthenticationSession> {
|
||||
const authenticationSessions = await authentication.getSessions('github', scopes);
|
||||
|
||||
if (authenticationSessions.length) {
|
||||
return await authenticationSessions[0];
|
||||
} else {
|
||||
return await authentication.login('github', scopes);
|
||||
}
|
||||
return await authentication.getSession('github', scopes, { createIfNone: true });
|
||||
}
|
||||
|
||||
let _octokit: Promise<Octokit> | undefined;
|
||||
|
||||
export function getOctokit(): Promise<Octokit> {
|
||||
if (!_octokit) {
|
||||
_octokit = getSession().then(async session => {
|
||||
const token = await session.getAccessToken();
|
||||
_octokit = getSession().then(session => {
|
||||
const token = session.accessToken;
|
||||
const agent = getAgent();
|
||||
|
||||
return new Octokit({
|
||||
|
|
|
@ -17,7 +17,7 @@ class GitHubCredentialProvider implements CredentialsProvider {
|
|||
}
|
||||
|
||||
const session = await getSession();
|
||||
return { username: session.account.id, password: await session.getAccessToken() };
|
||||
return { username: session.account.id, password: session.accessToken };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -205,9 +205,9 @@ export class AzureActiveDirectoryService {
|
|||
}, 1000 * 30);
|
||||
}
|
||||
|
||||
private async convertToSession(token: IToken): Promise<vscode.AuthenticationSession2> {
|
||||
private async convertToSession(token: IToken): Promise<vscode.AuthenticationSession> {
|
||||
const resolvedToken = await this.resolveAccessToken(token);
|
||||
return new vscode.AuthenticationSession2(token.sessionId, resolvedToken, token.account, token.scope.split(' '));
|
||||
return new vscode.AuthenticationSession(token.sessionId, resolvedToken, token.account, token.scope.split(' '));
|
||||
}
|
||||
|
||||
private async resolveAccessToken(token: IToken): Promise<string> {
|
||||
|
@ -240,11 +240,11 @@ export class AzureActiveDirectoryService {
|
|||
}
|
||||
}
|
||||
|
||||
get sessions(): Promise<vscode.AuthenticationSession2[]> {
|
||||
get sessions(): Promise<vscode.AuthenticationSession[]> {
|
||||
return Promise.all(this._tokens.map(token => this.convertToSession(token)));
|
||||
}
|
||||
|
||||
public async login(scope: string): Promise<vscode.AuthenticationSession2> {
|
||||
public async login(scope: string): Promise<vscode.AuthenticationSession> {
|
||||
Logger.info('Logging in...');
|
||||
if (!scope.includes('offline_access')) {
|
||||
Logger.info('Warning: The \'offline_access\' scope was not included, so the generated token will not be able to be refreshed.');
|
||||
|
@ -338,7 +338,7 @@ export class AzureActiveDirectoryService {
|
|||
}
|
||||
}
|
||||
|
||||
private async loginWithoutLocalServer(scope: string): Promise<vscode.AuthenticationSession2> {
|
||||
private async loginWithoutLocalServer(scope: string): Promise<vscode.AuthenticationSession> {
|
||||
const callbackUri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.microsoft-authentication`));
|
||||
const nonce = crypto.randomBytes(16).toString('base64');
|
||||
const port = (callbackUri.authority.match(/:([0-9]*)$/) || [])[1] || (callbackUri.scheme === 'https' ? 443 : 80);
|
||||
|
@ -353,7 +353,7 @@ export class AzureActiveDirectoryService {
|
|||
});
|
||||
vscode.env.openExternal(uri);
|
||||
|
||||
const timeoutPromise = new Promise((_: (value: vscode.AuthenticationSession2) => void, reject) => {
|
||||
const timeoutPromise = new Promise((_: (value: vscode.AuthenticationSession) => void, reject) => {
|
||||
const wait = setTimeout(() => {
|
||||
clearTimeout(wait);
|
||||
reject('Login timed out.');
|
||||
|
@ -363,9 +363,9 @@ export class AzureActiveDirectoryService {
|
|||
return Promise.race([this.handleCodeResponse(state, codeVerifier, scope), timeoutPromise]);
|
||||
}
|
||||
|
||||
private async handleCodeResponse(state: string, codeVerifier: string, scope: string): Promise<vscode.AuthenticationSession2> {
|
||||
private async handleCodeResponse(state: string, codeVerifier: string, scope: string): Promise<vscode.AuthenticationSession> {
|
||||
let uriEventListener: vscode.Disposable;
|
||||
return new Promise((resolve: (value: vscode.AuthenticationSession2) => void, reject) => {
|
||||
return new Promise((resolve: (value: vscode.AuthenticationSession) => void, reject) => {
|
||||
uriEventListener = this._uriHandler.event(async (uri: vscode.Uri) => {
|
||||
try {
|
||||
const query = parseQuery(uri);
|
||||
|
|
42
src/vs/vscode.proposed.d.ts
vendored
42
src/vs/vscode.proposed.d.ts
vendored
|
@ -20,17 +20,7 @@ declare module 'vscode' {
|
|||
|
||||
// #region auth provider: https://github.com/microsoft/vscode/issues/88309
|
||||
|
||||
export interface AuthenticationSession {
|
||||
id: string;
|
||||
getAccessToken(): Thenable<string>;
|
||||
account: {
|
||||
displayName: string;
|
||||
id: string;
|
||||
};
|
||||
scopes: string[];
|
||||
}
|
||||
|
||||
export class AuthenticationSession2 {
|
||||
export class AuthenticationSession {
|
||||
/**
|
||||
* The identifier of the authentication session.
|
||||
*/
|
||||
|
@ -148,12 +138,12 @@ declare module 'vscode' {
|
|||
/**
|
||||
* Returns an array of current sessions.
|
||||
*/
|
||||
getSessions(): Thenable<ReadonlyArray<AuthenticationSession2>>;
|
||||
getSessions(): Thenable<ReadonlyArray<AuthenticationSession>>;
|
||||
|
||||
/**
|
||||
* Prompts a user to login.
|
||||
*/
|
||||
login(scopes: string[]): Thenable<AuthenticationSession2>;
|
||||
login(scopes: string[]): Thenable<AuthenticationSession>;
|
||||
|
||||
/**
|
||||
* Removes the session corresponding to session id.
|
||||
|
@ -211,7 +201,7 @@ declare module 'vscode' {
|
|||
* @param options The [getSessionOptions](#GetSessionOptions) to use
|
||||
* @returns A thenable that resolves to an authentication session
|
||||
*/
|
||||
export function getSession(providerId: string, scopes: string[], options: AuthenticationGetSessionOptions & { createIfNone: true }): Thenable<AuthenticationSession2>;
|
||||
export function getSession(providerId: string, scopes: string[], options: AuthenticationGetSessionOptions & { createIfNone: true }): Thenable<AuthenticationSession>;
|
||||
|
||||
/**
|
||||
* Get an authentication session matching the desired scopes. Rejects if a provider with providerId is not
|
||||
|
@ -223,29 +213,7 @@ declare module 'vscode' {
|
|||
* @param options The [getSessionOptions](#GetSessionOptions) to use
|
||||
* @returns A thenable that resolves to an authentication session if available, or undefined if there are no sessions
|
||||
*/
|
||||
export function getSession(providerId: string, scopes: string[], options: AuthenticationGetSessionOptions): Thenable<AuthenticationSession2 | undefined>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Get existing authentication sessions. Rejects if a provider with providerId is not
|
||||
* registered, or if the user does not consent to sharing authentication information with
|
||||
* the extension.
|
||||
* @param providerId The id of the provider to use
|
||||
* @param scopes A list of scopes representing the permissions requested. These are dependent on the authentication
|
||||
* provider
|
||||
*/
|
||||
export function getSessions(providerId: string, scopes: string[]): Thenable<ReadonlyArray<AuthenticationSession>>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Prompt a user to login to create a new authenticaiton session. Rejects if a provider with
|
||||
* providerId is not registered, or if the user does not consent to sharing authentication
|
||||
* information with the extension.
|
||||
* @param providerId The id of the provider to use
|
||||
* @param scopes A list of scopes representing the permissions requested. These are dependent on the authentication
|
||||
* provider
|
||||
*/
|
||||
export function login(providerId: string, scopes: string[]): Thenable<AuthenticationSession>;
|
||||
export function getSession(providerId: string, scopes: string[], options: AuthenticationGetSessionOptions): Thenable<AuthenticationSession | undefined>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
|
|
|
@ -206,12 +206,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
getSession(providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions) {
|
||||
return extHostAuthentication.getSession(extension, providerId, scopes, options as any);
|
||||
},
|
||||
getSessions(providerId: string, scopes: string[]): Thenable<readonly vscode.AuthenticationSession[]> {
|
||||
return extHostAuthentication.getSessions(extension, providerId, scopes);
|
||||
},
|
||||
login(providerId: string, scopes: string[]): Thenable<vscode.AuthenticationSession> {
|
||||
return extHostAuthentication.login(extension, providerId, scopes);
|
||||
},
|
||||
logout(providerId: string, sessionId: string): Thenable<void> {
|
||||
return extHostAuthentication.logout(providerId, sessionId);
|
||||
},
|
||||
|
@ -1102,7 +1096,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
CellKind: extHostTypes.CellKind,
|
||||
CellOutputKind: extHostTypes.CellOutputKind,
|
||||
NotebookCellRunState: extHostTypes.NotebookCellRunState,
|
||||
AuthenticationSession2: extHostTypes.AuthenticationSession
|
||||
AuthenticationSession: extHostTypes.AuthenticationSession
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -56,8 +56,8 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
|||
return !!(sessions.filter(session => session.scopes.sort().join(' ') === orderedScopes).length);
|
||||
}
|
||||
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions & { createIfNone: true }): Promise<vscode.AuthenticationSession2>;
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions): Promise<vscode.AuthenticationSession2 | undefined> {
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions & { createIfNone: true }): Promise<vscode.AuthenticationSession>;
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions): Promise<vscode.AuthenticationSession | undefined> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
const extensionName = requestingExtension.displayName || requestingExtension.name;
|
||||
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
|
||||
|
@ -100,71 +100,6 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
|||
}
|
||||
}
|
||||
|
||||
async getSessions(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<readonly vscode.AuthenticationSession[]> {
|
||||
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
|
||||
const orderedScopes = scopes.sort().join(' ');
|
||||
const sessions = await this.resolveSessions(providerId);
|
||||
return sessions
|
||||
.filter(session => session.scopes.sort().join(' ') === orderedScopes)
|
||||
.map(session => {
|
||||
return {
|
||||
id: session.id,
|
||||
account: session.account,
|
||||
scopes: session.scopes,
|
||||
getAccessToken: async () => {
|
||||
const isAllowed = await this._proxy.$getSessionsPrompt(
|
||||
providerId,
|
||||
session.account.displayName,
|
||||
'', // TODO
|
||||
// provider.displayName,
|
||||
extensionId,
|
||||
requestingExtension.displayName || requestingExtension.name);
|
||||
|
||||
if (!isAllowed) {
|
||||
throw new Error('User did not consent to token access.');
|
||||
}
|
||||
|
||||
return session.accessToken;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async login(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<vscode.AuthenticationSession> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
if (!provider) {
|
||||
throw new Error(`No authentication provider with id '${providerId}' is currently registered.`);
|
||||
}
|
||||
|
||||
const extensionName = requestingExtension.displayName || requestingExtension.name;
|
||||
const isAllowed = await this._proxy.$loginPrompt(provider.displayName, extensionName);
|
||||
if (!isAllowed) {
|
||||
throw new Error('User did not consent to login.');
|
||||
}
|
||||
|
||||
const session = await provider.login(scopes);
|
||||
await this._proxy.$setTrustedExtension(provider.id, session.account.displayName, ExtensionIdentifier.toKey(requestingExtension.identifier), extensionName);
|
||||
return {
|
||||
id: session.id,
|
||||
account: session.account,
|
||||
scopes: session.scopes,
|
||||
getAccessToken: async () => {
|
||||
const isAllowed = await this._proxy.$getSessionsPrompt(
|
||||
provider.id,
|
||||
session.account.displayName,
|
||||
provider.displayName,
|
||||
ExtensionIdentifier.toKey(requestingExtension.identifier),
|
||||
requestingExtension.displayName || requestingExtension.name);
|
||||
|
||||
if (!isAllowed) {
|
||||
throw new Error('User did not consent to token access.');
|
||||
}
|
||||
|
||||
return session.accessToken;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async logout(providerId: string, sessionId: string): Promise<void> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
if (!provider) {
|
||||
|
|
|
@ -2769,7 +2769,7 @@ export enum ExtensionMode {
|
|||
|
||||
|
||||
//#region Authentication
|
||||
export class AuthenticationSession implements vscode.AuthenticationSession2 {
|
||||
export class AuthenticationSession implements vscode.AuthenticationSession {
|
||||
constructor(public id: string, public accessToken: string, public account: { displayName: string, id: string }, public scopes: string[]) { }
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue